Skip to content

Commit

Permalink
Merge pull request #3 from eagerworks/matrix-rspec
Browse files Browse the repository at this point in the history
Add CI and rspec matrix
  • Loading branch information
federicoaldunate authored Oct 1, 2024
2 parents 52a07ec + 4e7217b commit d4d2258
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 106 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Test Matrix

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
gemfile: [5_2.gemfile, 6_1.gemfile, 7_0.gemfile, 7_1.gemfile, 7_2.gemfile]
ruby-version: [ '2.7', '3.0', '3.1', '3.3']
exclude:
- ruby-version: '2.7'
gemfile: '7_0.gemfile'
- ruby-version: '2.7'
gemfile: '7_1.gemfile'
- ruby-version: '2.7'
gemfile: '7_2.gemfile'
- ruby-version: '3.0'
gemfile: '5_2.gemfile'
- ruby-version: '3.1'
gemfile: '5_2.gemfile'
- ruby-version: '3.3'
gemfile: '5_2.gemfile'

env:
BUNDLE_GEMFILE: spec/gemfiles/${{ matrix.gemfile }}
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true

- name: Install dependencies
run: |
gem install bundler
bundle install
- name: Run tests
run: |
bundle exec rspec
3 changes: 2 additions & 1 deletion lib/sea_food/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class << self
# @param args [Hash] Arguments to pass to the service.
# @return [ServiceResult] The result of the service call.
def call(params = {})
service = new(params)
# debugger
service = new(**params)
service.call
service.result || ServiceResult.new
rescue ServiceError => e
Expand Down
3 changes: 3 additions & 0 deletions spec/gemfiles/6_1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source 'https://rubygems.org'
gemspec path: '../..'
gem 'rails', '~> 6.1'
4 changes: 4 additions & 0 deletions spec/gemfiles/7_0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'
gemspec path: '../..'
gem 'rails', '~> 7.0'
gem 'sqlite3', '~> 1.5.0'
4 changes: 4 additions & 0 deletions spec/gemfiles/7_1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'
gemspec path: '../..'
gem 'rails', '~> 7.1'
gem 'sqlite3', '~> 1.5.0'
4 changes: 4 additions & 0 deletions spec/gemfiles/7_2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'
gemspec path: '../..'
gem 'rails', '~> 7.2'
gem 'sqlite3', '~> 1.5.0'
231 changes: 126 additions & 105 deletions spec/sea_food/service/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,156 +70,177 @@ def call
# Test enforcing the interface of the service
######

it '.call - fails on missing arguments' do
TestFailOnMissingArgsService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
context "when the configuration is set to enforce the interface" do
before do
SeaFood.configure do |config|
config.enforce_interface = true
end
end

def call
success(email: email)
it 'rasies an error when the #initialize method is not implemented' do
TestService = Class.new(SeaFood::Service) do
def call
end
end
end

expect { TestFailOnMissingArgsService.call }.to raise_error(
ArgumentError
).with_message('missing keyword: :email')
end
expect { TestService.call }.to raise_error(
NotImplementedError
).with_message(
'Subclasses must implement the initialize '\
'method because `enforce_interface` is set to true'
)
end

it '.call - success with arguments' do
TestSuccessWithArgsService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
it 'does not rasies an error when the #initialize method is implemented' do
TestService = Class.new(SeaFood::Service) do
def initialize; end
def call; end
end

def call
success(email: @email)
end
expect { TestService.call }.not_to raise_error(
NotImplementedError
)
end

result = TestSuccessWithArgsService.call(email: '[email protected]')
expect(result).to be_success
expect(result.email).to eq('[email protected]')
end
it '.call - fails on missing arguments' do
TestFailOnMissingArgsService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

it '.call - success default with arguments ' do
TestSuccessWithArgsService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
def call
success(email: email)
end
end

def call; end
expect { TestFailOnMissingArgsService.call }.to raise_error(
ArgumentError
).with_message('missing keyword: :email')
end

result = TestSuccessWithArgsService.call(email: '[email protected]')
expect(result).to be_success
expect(result.email).to be_nil
end

######
# Test the difference behavior of #success #fail #fail!
######
it '.call - success with arguments' do
TestSuccessWithArgsService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

it 'call #success twice' do
TestSuccessService = Class.new(SeaFood::Service) do
def call
success(email: '[email protected]')
success(email: params[:email])
def call
success(email: @email)
end
end
end

result = TestSuccessService.call(email: '[email protected]')
result = TestSuccessWithArgsService.call(email: '[email protected]')
expect(result).to be_success
expect(result.email).to eq('[email protected]')
end

expect(result).to be_success
expect(result.email).to eq('[email protected]')
end
it '.call - success default with arguments ' do
TestSuccessWithArgsService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

it 'call #fail twice' do
TestFailService = Class.new(SeaFood::Service) do
def call
fail(email: '[email protected]')
fail(email: params[:email])
def call; end
end

result = TestSuccessWithArgsService.call(email: '[email protected]')
expect(result).to be_success
expect(result.email).to be_nil
end

result = TestFailService.call(email: '[email protected]')
######
# Test the difference behavior of #success #fail #fail!
######

expect(result).to be_fail
expect(result.email).to eq('[email protected]')
end
it 'call #success twice' do
TestSuccessService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

it 'call #fail! twice' do
TestFailService = Class.new(SeaFood::Service) do
def call
fail!(email: '[email protected]')
fail!(email: params[:email])
def call
success(email: '[email protected]')
success(email: @email)
end
end
end

result = TestFailService.call(email: '[email protected]')

expect(result).to be_fail
expect(result.email).to eq('[email protected]')
end
result = TestSuccessService.call(email: '[email protected]')

it '#fail then #success' do
TestFailService = Class.new(SeaFood::Service) do
def call
fail(email: '[email protected]')
success(email: params[:email])
end
expect(result).to be_success
expect(result.email).to eq('[email protected]')
end

result = TestFailService.call(email: '[email protected]')

expect(result).to be_success
expect(result.email).to eq('[email protected]')
end
it 'call #fail twice' do
TestFailService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

it '#fail! then #success!' do
TestFailService = Class.new(SeaFood::Service) do
def call
fail!(email: '[email protected]')
success!(email: params[:email])
def call
fail(email: '[email protected]')
fail(email: @email)
end
end
end

result = TestFailService.call(email: '[email protected]')
result = TestFailService.call(email: '[email protected]')

expect(result).to be_fail
expect(result.email).to eq('hi@example.com')
end
expect(result).to be_fail
expect(result.email).to eq('service@example.com')
end

context "when the configuration is set to enforce the interface" do
before do
SeaFood.configure do |config|
config.enforce_interface = true
it 'call #fail! twice' do
TestFailService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

def call
fail!(email: '[email protected]')
fail!(email: @email)
end
end

result = TestFailService.call(email: '[email protected]')

expect(result).to be_fail
expect(result.email).to eq('[email protected]')
end

it 'rasies an error when the #initialize method is not implemented' do
TestService = Class.new(SeaFood::Service) do
it '#fail then #success' do
TestFailService = Class.new(SeaFood::Service) do

def initialize(email:)
@email = email
end

def call
fail(email: '[email protected]')
success(email: @email)
end
end

expect { TestService.call }.to raise_error(
NotImplementedError
).with_message(
'Subclasses must implement the initialize '\
'method because `enforce_interface` is set to true'
)
result = TestFailService.call(email: '[email protected]')

expect(result).to be_success
expect(result.email).to eq('[email protected]')
end

it ' does not rasies an error when the #initialize method is implemented' do
TestService = Class.new(SeaFood::Service) do
def initialize; end
def call; end
it '#fail! then #success!' do
TestFailService = Class.new(SeaFood::Service) do
def initialize(email:)
@email = email
end

def call
fail!(email: '[email protected]')
success!(email: @email)
end
end

expect { TestService.call }.not_to raise_error(
NotImplementedError
)
result = TestFailService.call(email: '[email protected]')

expect(result).to be_fail
expect(result.email).to eq('[email protected]')
end
end
end

0 comments on commit d4d2258

Please sign in to comment.