From a5a258f6f023d45d267428aeedb5ff87f02da952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jessica=20=C3=89t=C3=A9?= Date: Sun, 18 Sep 2022 13:42:03 +0200 Subject: [PATCH 1/3] Add SimpleCov to the test suite Though the gem will support non-Rails applications, I have decided to use the `:rails` profile in SimpleCov as this was the easiest way to ensure that the correct files were added to the code coverage statistics. --- Gemfile.lock | 59 +++++++++++++++++++++++++++++++++++++++ amazon_ses_mailer.gemspec | 2 ++ spec/spec_helper.rb | 27 +++++++++++++++++- 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..5ebd8cf --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,59 @@ +PATH + remote: . + specs: + amazon_ses_mailer (0.1.0) + aws-sdk-sesv2 (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + aws-eventstream (1.2.0) + aws-partitions (1.631.0) + aws-sdk-core (3.149.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.525.0) + aws-sigv4 (~> 1.1) + jmespath (~> 1, >= 1.6.1) + aws-sdk-sesv2 (1.27.0) + aws-sdk-core (~> 3, >= 3.127.0) + aws-sigv4 (~> 1.1) + aws-sigv4 (1.5.1) + aws-eventstream (~> 1, >= 1.0.2) + diff-lcs (1.5.0) + docile (1.3.5) + jmespath (1.6.1) + json (2.6.2) + rake (10.5.0) + rspec (3.11.0) + rspec-core (~> 3.11.0) + rspec-expectations (~> 3.11.0) + rspec-mocks (~> 3.11.0) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.11.0) + rspec-support (3.11.1) + simplecov (0.17.1) + docile (~> 1.1) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) + simplecov-lcov (0.7.0) + +PLATFORMS + ruby + +DEPENDENCIES + amazon_ses_mailer! + bundler (~> 1.17) + rake (~> 10.0) + rspec (~> 3.0) + simplecov (~> 0.17.1) + simplecov-lcov (~> 0.7.0) + +BUNDLED WITH + 1.17.3 diff --git a/amazon_ses_mailer.gemspec b/amazon_ses_mailer.gemspec index 7182ab2..b7b605f 100644 --- a/amazon_ses_mailer.gemspec +++ b/amazon_ses_mailer.gemspec @@ -24,6 +24,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", "~> 1.17" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "simplecov", "~> 0.17.1" + spec.add_development_dependency "simplecov-lcov", "~> 0.7.0" spec.add_runtime_dependency "aws-sdk-sesv2", "~> 1.0" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d0acb7a..36c1bf4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,23 @@ -require "bundler/setup" require "amazon_ses_mailer" +require 'simplecov' +require 'simplecov-lcov' + +SimpleCov.start :rails do + if ENV['CI'] + SimpleCov::Formatter::LcovFormatter.config do |config| + config.report_with_single_file = true + config.single_report_path = 'coverage/lcov.info' + end + + SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [ + SimpleCov::Formatter::LcovFormatter + ] + else + SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [ + SimpleCov::Formatter::HTMLFormatter + ] + end +end RSpec.configure do |config| # Enable flags like --only-failures and --next-failure @@ -10,5 +28,12 @@ config.expect_with :rspec do |c| c.syntax = :expect + c.include_chain_clauses_in_custom_matcher_descriptions = true end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + + config.shared_context_metadata_behavior = :apply_to_host_groups end From 04613a2f4ee2705f35123c0cc82b2b51168ba551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jessica=20=C3=89t=C3=A9?= Date: Sun, 18 Sep 2022 21:33:27 +0200 Subject: [PATCH 2/3] Monkeypatch the Hash#transform_values method This is a Rails method [1] used in the Base class. In order to support non-rails applications, it's necessary to monkeypatch the Hash class. [1]: https://apidock.com/rails/v5.2.3/Hash/transform_values --- lib/amazon_ses_mailer/base.rb | 2 ++ lib/core_extensions/hash.rb | 15 +++++++++++++++ spec/core_extensions/hash_spec.rb | 10 ++++++++++ 3 files changed, 27 insertions(+) create mode 100644 lib/core_extensions/hash.rb create mode 100644 spec/core_extensions/hash_spec.rb diff --git a/lib/amazon_ses_mailer/base.rb b/lib/amazon_ses_mailer/base.rb index 0e9c741..af15821 100644 --- a/lib/amazon_ses_mailer/base.rb +++ b/lib/amazon_ses_mailer/base.rb @@ -1,3 +1,5 @@ +require "./lib/core_extensions/hash.rb" + module AmazonSesMailer class Base attr_reader :template_name diff --git a/lib/core_extensions/hash.rb b/lib/core_extensions/hash.rb new file mode 100644 index 0000000..3ef223f --- /dev/null +++ b/lib/core_extensions/hash.rb @@ -0,0 +1,15 @@ +module CoreExtensions + module Hash + def transform_values + return enum_for(:transform_values) { size } unless block_given? + return {} if empty? + result = self.class.new + each do |key, value| + result[key] = yield(value) + end + result + end + end +end + +Hash.include CoreExtensions::Hash diff --git a/spec/core_extensions/hash_spec.rb b/spec/core_extensions/hash_spec.rb new file mode 100644 index 0000000..8fa2810 --- /dev/null +++ b/spec/core_extensions/hash_spec.rb @@ -0,0 +1,10 @@ +RSpec.describe CoreExtensions::Hash do + describe '#transform_values' do + it 'transforms hash values' do + original = { a: 'a', b: 'b' } + mapped = original.transform_values { |val| "#{val}!" } + + expect(mapped[:a]).to eq 'a!' + end + end +end From d5546d8e3f7c6e19ff4fe7c84414c8eac1c5ef9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jessica=20=C3=89t=C3=A9?= Date: Mon, 19 Sep 2022 03:04:23 +0200 Subject: [PATCH 3/3] Add single test for Base#mail method This commit adds a test to ensure that a new Message instance is created when the `Base#mail` method is called. In order to do this, it was necessary to add a new private method to the Base class as the `instance_variable_names` method called is a Rails-only method [1] and so would have raised an exception in a non-Rails application. [1]: https://apidock.com/rails/v5.2.3/Object/instance_variable_names --- lib/amazon_ses_mailer/base.rb | 14 +++++++++----- spec/amazon_ses_mailer/base_spec.rb | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 spec/amazon_ses_mailer/base_spec.rb diff --git a/lib/amazon_ses_mailer/base.rb b/lib/amazon_ses_mailer/base.rb index af15821..e107ac8 100644 --- a/lib/amazon_ses_mailer/base.rb +++ b/lib/amazon_ses_mailer/base.rb @@ -6,7 +6,7 @@ class Base class << self attr_accessor :default_options, :delivery_method - + def deliveries @@_deliveries ||= [] end @@ -59,9 +59,9 @@ def process_merge_vars(merge_vars) end def convert_instance_variables_to_merge_vars - self.instance_variable_names.reduce({}) do |result, variable_name| + instance_variable_names.reduce({}) do |result, variable_name| key = variable_name.delete "@" - value = self.instance_variable_get(variable_name) + value = instance_variable_get(variable_name) result.merge!(key => value) end end @@ -69,11 +69,11 @@ def convert_instance_variables_to_merge_vars def transform_hash(hash) hash.transform_values{ |value| transform_value(value) } end - + def transform_array(arr) arr.map{|value| transform_value(value)} end - + def transform_value(value) # recurse on hashes/arrays, converts nil/false values to empty strings, and converts all others to strings return '' unless !!value @@ -81,5 +81,9 @@ def transform_value(value) return transform_array(value) if value.is_a?(Array) return value.to_s end + + def instance_variable_names + instance_variables.map(&:to_s) + end end end diff --git a/spec/amazon_ses_mailer/base_spec.rb b/spec/amazon_ses_mailer/base_spec.rb new file mode 100644 index 0000000..9142b9d --- /dev/null +++ b/spec/amazon_ses_mailer/base_spec.rb @@ -0,0 +1,18 @@ +RSpec.describe AmazonSesMailer::Base do + let(:options) { {} } + let(:template_name) { '' } + let(:delivery_method) { nil } + subject { described_class.new(template_name) } + + describe '#mail' do + before do + allow(AmazonSesMailer::Base).to receieve(:delivery_method) + .and_return(delivery_method) + end + + it 'creates a new message' do + expect(AmazonSesMailer::Message).to receive(:new) + subject.mail(options) + end + end +end