Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit f59ed92

Browse files
committed
Merge pull request #3 from nisshiee/mock-test
Add mock test
2 parents f6c96dc + ecf10b7 commit f59ed92

File tree

7 files changed

+241
-40
lines changed

7 files changed

+241
-40
lines changed

lib/validation_examples_matcher.rb

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,49 @@
22
require 'rspec/expectations'
33

44
module ValidationExamplesMatcher
5-
RSpec::Matchers.define :be_valid_on do |attr_name|
6-
match do |model|
7-
model.send("#{attr_name}=", @value)
8-
model.valid?(@context)
9-
end
5+
def self.register(matchers = RSpec::Matchers)
6+
matchers.define :be_valid_on do |attr_name|
7+
match do |model|
8+
model.send("#{attr_name}=", @value)
9+
model.valid?(@context)
10+
end
1011

11-
chain :with do |value|
12-
@value = value
13-
end
12+
chain :with do |value|
13+
@value = value
14+
end
1415

15-
chain :on_context do |context|
16-
@context = context
17-
end
16+
chain :on_context do |context|
17+
@context = context
18+
end
1819

19-
failure_message do |model|
20-
if model.invalid?(@context)
20+
failure_message do |model|
2121
"expect #{model.class} to be valid, but it is INVALID."
22-
else
23-
"expect #{model.class} to have errors on #{attr_name}, but there is NO ERROR."
2422
end
2523
end
26-
end
2724

28-
RSpec::Matchers.define :be_invalid_on do |attr_name|
29-
match do |model|
30-
model.send("#{attr_name}=", @value)
31-
model.invalid?(@context) && model.errors[attr_name].size >= 1
32-
end
25+
matchers.define :be_invalid_on do |attr_name|
26+
match do |model|
27+
model.send("#{attr_name}=", @value)
28+
model.invalid?(@context) && model.errors[attr_name].size >= 1
29+
end
3330

34-
chain :with do |value|
35-
@value = value
36-
end
31+
chain :with do |value|
32+
@value = value
33+
end
3734

38-
chain :on_context do |context|
39-
@context = context
40-
end
35+
chain :on_context do |context|
36+
@context = context
37+
end
4138

42-
failure_message do |model|
43-
if model.valid?(@context)
44-
"expect #{model.class} to be invalid but it is VALID"
45-
else
46-
"expect #{model.class} to have errors on #{attr_name} but EMPTY"
39+
failure_message do |model|
40+
if model.valid?(@context)
41+
"expect #{model.class} to be invalid, but it is VALID."
42+
else
43+
"expect #{model.class} to have errors on #{attr_name}, but EMPTY."
44+
end
4745
end
4846
end
4947
end
48+
49+
register
5050
end

spec/examples/validations_spec.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
require 'spec_helper'
22

3-
class TestModel
4-
include ActiveModel::Model
5-
6-
attr_accessor :attr
7-
validates :attr, presence: true
8-
validates :attr, length: { maximum: 4 }, on: :a_context
9-
end
10-
113
RSpec.describe TestModel do
124
subject { TestModel.new }
135

spec/spec_helper.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
11
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
22
require 'validation_examples_matcher'
33
require 'active_model'
4+
require 'pry'
5+
6+
class TestModel
7+
include ActiveModel::Model
8+
9+
attr_accessor :attr
10+
validates :attr, presence: true
11+
validates :attr, length: { maximum: 4 }, on: :a_context
12+
end
13+
14+
class MatchersMock < BasicObject
15+
attr_reader :defined_matchers, :match_blocks, :chain_blocks, :failure_message_blocks
16+
attr_reader :value, :context
17+
18+
def define(name, &block)
19+
@defined_matchers ||= []
20+
@defined_matchers << name
21+
@current = name
22+
instance_exec(:attr, &block)
23+
end
24+
25+
def match(&block)
26+
@match_blocks ||= {}
27+
@match_blocks[@current] = block
28+
end
29+
30+
def chain(name, &block)
31+
@chain_blocks ||= {}
32+
@chain_blocks[@current] ||= {}
33+
@chain_blocks[@current][name] = block
34+
end
35+
36+
def failure_message(&block)
37+
@failure_message_blocks ||= {}
38+
@failure_message_blocks[@current] = block
39+
end
40+
end
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe 'be_invalid_on matcher' do
4+
let(:matchers) { MatchersMock.new }
5+
before { ValidationExamplesMatcher.register(matchers) }
6+
let(:model) { TestModel.new }
7+
8+
let(:match_block) { matchers.match_blocks[:be_invalid_on] }
9+
let(:chain_blocks) { matchers.chain_blocks[:be_invalid_on] }
10+
let(:with_chain_block) { chain_blocks[:with] }
11+
let(:on_context_chain_block) { chain_blocks[:on_context] }
12+
let(:failure_message_block) { matchers.failure_message_blocks[:be_invalid_on] }
13+
14+
it 'is registered with match block' do
15+
expect(match_block).to be_kind_of(Proc)
16+
end
17+
18+
describe 'match block' do
19+
let(:model) { double('model') }
20+
before { matchers.instance_exec(:a_value, &with_chain_block) }
21+
22+
context 'without on_context chain' do
23+
it "calls model's setter and valid?" do
24+
expect(model).to receive(:attr=).with(:a_value)
25+
expect(model).to receive(:invalid?).with(nil)
26+
matchers.instance_exec(model, &match_block)
27+
end
28+
end
29+
30+
context 'with on_context chain' do
31+
before { matchers.instance_exec(:a_context, &on_context_chain_block) }
32+
it "calls model's setter and valid?" do
33+
expect(model).to receive(:attr=).with(:a_value)
34+
expect(model).to receive(:invalid?).with(:a_context)
35+
matchers.instance_exec(model, &match_block)
36+
end
37+
end
38+
end
39+
40+
it 'is registered with :with chain block' do
41+
expect(with_chain_block).to be_kind_of(Proc)
42+
end
43+
44+
describe 'with chain block' do
45+
it 'sets @value' do
46+
matchers.instance_exec(:a_value, &with_chain_block)
47+
expect(matchers.value).to eq :a_value
48+
end
49+
end
50+
51+
it 'is registered with :on_context chain block' do
52+
expect(on_context_chain_block).to be_kind_of(Proc)
53+
end
54+
55+
describe 'with on_context block' do
56+
it 'sets @context' do
57+
matchers.instance_exec(:a_context, &on_context_chain_block)
58+
expect(matchers.context).to eq :a_context
59+
end
60+
end
61+
62+
63+
it 'is registered with failure_message block' do
64+
expect(failure_message_block).to be_kind_of(Proc)
65+
end
66+
67+
describe 'failure_message block' do
68+
context 'the model is valid' do
69+
before { model.attr = 'ok' }
70+
it 'returns message saying "it should be invalid"' do
71+
expect(matchers.instance_exec(model, &failure_message_block))
72+
.to eq 'expect TestModel to be invalid, but it is VALID.'
73+
end
74+
end
75+
76+
context 'the model is invalid but it has no errors' do
77+
let(:model) { double('model') }
78+
it 'returns message saying "it should have errors"' do
79+
expect(model).to receive(:valid?) { false }
80+
expect(matchers.instance_exec(model, &failure_message_block))
81+
.to eq 'expect RSpec::Mocks::Double to have errors on attr, but EMPTY.'
82+
end
83+
end
84+
end
85+
end
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe 'be_valid_on matcher' do
4+
let(:matchers) { MatchersMock.new }
5+
before { ValidationExamplesMatcher.register(matchers) }
6+
let(:model) { TestModel.new }
7+
8+
let(:match_block) { matchers.match_blocks[:be_valid_on] }
9+
let(:chain_blocks) { matchers.chain_blocks[:be_valid_on] }
10+
let(:with_chain_block) { chain_blocks[:with] }
11+
let(:on_context_chain_block) { chain_blocks[:on_context] }
12+
let(:failure_message_block) { matchers.failure_message_blocks[:be_valid_on] }
13+
14+
it 'is registered with match block' do
15+
expect(match_block).to be_kind_of(Proc)
16+
end
17+
18+
describe 'match block' do
19+
let(:model) { double('model') }
20+
before { matchers.instance_exec(:a_value, &with_chain_block) }
21+
22+
context 'without on_context chain' do
23+
it "calls model's setter and valid?" do
24+
expect(model).to receive(:attr=).with(:a_value)
25+
expect(model).to receive(:valid?).with(nil)
26+
matchers.instance_exec(model, &match_block)
27+
end
28+
end
29+
30+
context 'with on_context chain' do
31+
before { matchers.instance_exec(:a_context, &on_context_chain_block) }
32+
it "calls model's setter and valid?" do
33+
expect(model).to receive(:attr=).with(:a_value)
34+
expect(model).to receive(:valid?).with(:a_context)
35+
matchers.instance_exec(model, &match_block)
36+
end
37+
end
38+
end
39+
40+
it 'is registered with :with chain block' do
41+
expect(with_chain_block).to be_kind_of(Proc)
42+
end
43+
44+
describe 'with chain block' do
45+
it 'sets @value' do
46+
matchers.instance_exec(:a_value, &with_chain_block)
47+
expect(matchers.value).to eq :a_value
48+
end
49+
end
50+
51+
it 'is registered with :on_context chain block' do
52+
expect(on_context_chain_block).to be_kind_of(Proc)
53+
end
54+
55+
describe 'with on_context block' do
56+
it 'sets @context' do
57+
matchers.instance_exec(:a_context, &on_context_chain_block)
58+
expect(matchers.context).to eq :a_context
59+
end
60+
end
61+
62+
63+
it 'is registered with failure_message block' do
64+
expect(failure_message_block).to be_kind_of(Proc)
65+
end
66+
67+
describe 'failure_message block' do
68+
context 'the model is invalid' do
69+
it 'returns message saying "it should be valid"' do
70+
expect(matchers.instance_exec(model, &failure_message_block))
71+
.to eq 'expect TestModel to be valid, but it is INVALID.'
72+
end
73+
end
74+
end
75+
end

spec/validation_examples_matcher_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,15 @@
44
it 'has a version number' do
55
expect(ValidationExamplesMatcher::VERSION).not_to be nil
66
end
7+
8+
let(:matchers) { MatchersMock.new }
9+
before { ValidationExamplesMatcher.register(matchers) }
10+
11+
it 'registers :be_valid_on matcher' do
12+
expect(matchers.defined_matchers).to include(:be_valid_on)
13+
end
14+
15+
it 'registers :be_invalid_on matcher' do
16+
expect(matchers.defined_matchers).to include(:be_invalid_on)
17+
end
718
end

validation_examples_matcher.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
2626
spec.add_development_dependency "rake", "~> 10.0"
2727
spec.add_development_dependency "rspec", "~> 3.0"
2828
spec.add_development_dependency "activemodel", "~> 4.2.5"
29+
spec.add_development_dependency "pry-byebug", "~> 3.3.0"
2930
end

0 commit comments

Comments
 (0)