sinclair 1.8.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +20 -6
- data/.rubocop.yml +5 -2
- data/Dockerfile +1 -1
- data/README.md +25 -1
- data/config/check_specs.yml +1 -0
- data/config/yardstick.yml +9 -1
- data/lib/sinclair/comparable/class_methods.rb +33 -0
- data/lib/sinclair/comparable.rb +47 -0
- data/lib/sinclair/config_builder.rb +4 -2
- data/lib/sinclair/configurable.rb +2 -0
- data/lib/sinclair/equals_checker.rb +110 -0
- data/lib/sinclair/matchers/add_class_method.rb +27 -36
- data/lib/sinclair/matchers/add_instance_method.rb +59 -59
- data/lib/sinclair/matchers/add_method.rb +33 -35
- data/lib/sinclair/matchers/change_class_method.rb +22 -16
- data/lib/sinclair/matchers/change_instance_method.rb +46 -16
- data/lib/sinclair/matchers.rb +2 -8
- data/lib/sinclair/method_builder/call_method_builder.rb +49 -0
- data/lib/sinclair/method_builder.rb +4 -1
- data/lib/sinclair/method_definition/call_definition.rb +52 -0
- data/lib/sinclair/method_definition/string_definition.rb +0 -2
- data/lib/sinclair/method_definition.rb +40 -24
- data/lib/sinclair/method_definitions.rb +21 -1
- data/lib/sinclair/options/builder.rb +8 -0
- data/lib/sinclair/options.rb +1 -13
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +2 -0
- data/sinclair.gemspec +1 -1
- data/spec/integration/readme/sinclair/comparable_spec.rb +24 -0
- data/spec/integration/yard/sinclair/comparable_spec.rb +24 -0
- data/spec/integration/yard/sinclair/equals_checker_spec.rb +51 -0
- data/spec/integration/yard/sinclair/matchers/change_class_method_spec.rb +24 -0
- data/spec/integration/yard/sinclair/matchers/change_instance_method_spec.rb +40 -0
- data/spec/lib/sinclair/comparable_spec.rb +202 -0
- data/spec/lib/sinclair/equals_checker_spec.rb +148 -0
- data/spec/lib/sinclair/method_builder/call_method_builder_spec.rb +76 -0
- data/spec/lib/sinclair/method_builder_spec.rb +63 -20
- data/spec/lib/sinclair/method_definition/call_definition_spec.rb +36 -0
- data/spec/lib/sinclair/method_definition_spec.rb +64 -0
- data/spec/lib/sinclair/method_definitions_spec.rb +79 -0
- data/spec/lib/sinclair/options/builder_spec.rb +13 -0
- data/spec/lib/sinclair/options/class_methods_spec.rb +23 -8
- data/spec/support/sample_model.rb +19 -0
- data/spec/support/shared_examples/attribute_accessor.rb +103 -0
- metadata +21 -5
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::EqualsChecker do
|
6
|
+
describe '#yard' do
|
7
|
+
describe '#match?' do
|
8
|
+
it 'regular usage' do
|
9
|
+
checker = Sinclair::EqualsChecker.new(:name, :age)
|
10
|
+
|
11
|
+
model1 = SampleModel.new(name: 'jack', age: 21)
|
12
|
+
model2 = SampleModel.new(name: 'rose', age: 23)
|
13
|
+
|
14
|
+
expect(checker.match?(model1, model2)).to be_falsey
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'similar models' do
|
18
|
+
checker = Sinclair::EqualsChecker.new(:name, :age)
|
19
|
+
|
20
|
+
model1 = SampleModel.new(name: 'jack', age: 21)
|
21
|
+
model2 = SampleModel.new(name: 'jack', age: 21)
|
22
|
+
|
23
|
+
expect(checker.match?(model1, model2)).to be_truthy
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'different classes' do
|
27
|
+
checker = Sinclair::EqualsChecker.new(:name, :age)
|
28
|
+
|
29
|
+
model1 = SampleModel.new(name: 'jack', age: 21)
|
30
|
+
model2 = OtherModel.new(name: 'jack', age: 21)
|
31
|
+
|
32
|
+
expect(checker.match?(model1, model2)).to be_falsey
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#add' do
|
37
|
+
it 'adding fields to equal checker' do
|
38
|
+
checker = Sinclair::EqualsChecker.new(:name)
|
39
|
+
|
40
|
+
model1 = SampleModel.new(name: 'jack', age: 21)
|
41
|
+
model2 = SampleModel.new(name: 'jack', age: 22)
|
42
|
+
|
43
|
+
expect(checker.match?(model1, model2)).to be_truthy
|
44
|
+
|
45
|
+
checker.add(:age)
|
46
|
+
|
47
|
+
expect(checker.match?(model1, model2)).to be_falsey
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Sinclair::Matchers::ChangeClassMethod do
|
6
|
+
describe 'yard' do
|
7
|
+
describe '#on' do
|
8
|
+
context 'when checking against Class' do
|
9
|
+
let(:klass) { Class.new(MyModel) }
|
10
|
+
let(:builder) { Sinclair.new(klass) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
builder.add_class_method(:the_method) { 10 }
|
14
|
+
builder.build
|
15
|
+
builder.add_class_method(:the_method) { 20 }
|
16
|
+
end
|
17
|
+
|
18
|
+
it do
|
19
|
+
expect { builder.build }.to change_class_method(:the_method).on(klass)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Sinclair::Matchers::ChangeInstanceMethod do
|
6
|
+
describe 'yard' do
|
7
|
+
describe '#on' do
|
8
|
+
context 'when checking against Class' do
|
9
|
+
let(:klass) { Class.new(MyModel) }
|
10
|
+
let(:builder) { Sinclair.new(klass) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
builder.add_method(:the_method) { 10 }
|
14
|
+
builder.build
|
15
|
+
builder.add_method(:the_method) { 20 }
|
16
|
+
end
|
17
|
+
|
18
|
+
it do
|
19
|
+
expect { builder.build }.to change_method(:the_method).on(klass)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when checking against an intance' do
|
24
|
+
let(:klass) { Class.new(MyModel) }
|
25
|
+
let(:instance) { klass.new }
|
26
|
+
let(:builder) { Sinclair.new(klass) }
|
27
|
+
|
28
|
+
before do
|
29
|
+
builder.add_method(:the_method) { 10 }
|
30
|
+
builder.build
|
31
|
+
builder.add_method(:the_method) { 20 }
|
32
|
+
end
|
33
|
+
|
34
|
+
it do
|
35
|
+
expect { builder.build }.to change_method(:the_method).on(instance)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Comparable do
|
6
|
+
let(:model_class) do
|
7
|
+
Class.new(SampleModel) do
|
8
|
+
include Sinclair::Comparable
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:attributes) { %i[] }
|
13
|
+
let(:model1_class) { model_class }
|
14
|
+
let(:model2_class) { model_class }
|
15
|
+
let(:model1) { model1_class.new(**model1_attributes) }
|
16
|
+
let(:model2) { model2_class.new(**model2_attributes) }
|
17
|
+
|
18
|
+
let(:model1_attributes) { { name: name1, age: age1 } }
|
19
|
+
let(:model2_attributes) { { name: name2, age: age2 } }
|
20
|
+
let(:name1) { SecureRandom.hex(10) }
|
21
|
+
let(:name2) { SecureRandom.hex(10) }
|
22
|
+
let(:age1) { Random.rand(10..20) }
|
23
|
+
let(:age2) { Random.rand(21..50) }
|
24
|
+
|
25
|
+
describe '.comparable_by' do
|
26
|
+
let(:model2_class) { model1_class }
|
27
|
+
|
28
|
+
context 'when no field was present' do
|
29
|
+
it 'adds the field for comparison' do
|
30
|
+
expect { model1_class.comparable_by(:name) }
|
31
|
+
.to change { model1 == model2 }
|
32
|
+
.from(true).to(false)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when there was a field present' do
|
37
|
+
let(:name2) { name1 }
|
38
|
+
|
39
|
+
before { model1_class.comparable_by(:name) }
|
40
|
+
|
41
|
+
it 'adds the field for comparison' do
|
42
|
+
expect { model1_class.comparable_by(:age) }
|
43
|
+
.to change { model1 == model2 }
|
44
|
+
.from(true).to(false)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when there was a field present and it made a non match' do
|
49
|
+
let(:age2) { age1 }
|
50
|
+
|
51
|
+
before { model1_class.comparable_by(:name) }
|
52
|
+
|
53
|
+
it 'adds the field for comparison without forgeting the previous' do
|
54
|
+
expect { model1_class.comparable_by(:age) }
|
55
|
+
.not_to change { model1 == model2 }
|
56
|
+
.from(false)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when the class parent class adds a field' do
|
61
|
+
let(:model1_class) { Class.new(model_class) }
|
62
|
+
let(:model2_class) { model1_class }
|
63
|
+
|
64
|
+
it 'takes the field into consideration' do
|
65
|
+
expect { model_class.comparable_by(:name) }
|
66
|
+
.to change { model1 == model2 }
|
67
|
+
.from(true).to(false)
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when we add a field to the class itself' do
|
71
|
+
let(:name2) { name1 }
|
72
|
+
|
73
|
+
before { model_class.comparable_by(:name) }
|
74
|
+
|
75
|
+
it 'takes all fields into consideration' do
|
76
|
+
expect { model1_class.comparable_by(:age) }
|
77
|
+
.to change { model1 == model2 }
|
78
|
+
.from(true).to(false)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when we add a field to the parent class after' do
|
83
|
+
let(:name2) { name1 }
|
84
|
+
|
85
|
+
before { model1_class.comparable_by(:name) }
|
86
|
+
|
87
|
+
it 'takes all fields into consideration' do
|
88
|
+
expect { model_class.comparable_by(:age) }
|
89
|
+
.to change { model1 == model2 }
|
90
|
+
.from(true).to(false)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#==' do
|
97
|
+
before do
|
98
|
+
model1_class.comparable_by(attributes)
|
99
|
+
model2_class.comparable_by(attributes)
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when the attributes is empty' do
|
103
|
+
context 'when they are different classes and attributes are the same' do
|
104
|
+
let(:model2_class) { Class.new(model1_class) }
|
105
|
+
let(:name2) { name1 }
|
106
|
+
let(:age2) { age1 }
|
107
|
+
|
108
|
+
it do
|
109
|
+
expect(model1).not_to eq(model2)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'when the models have the same attributes' do
|
114
|
+
let(:name2) { name1 }
|
115
|
+
let(:age2) { age1 }
|
116
|
+
|
117
|
+
it do
|
118
|
+
expect(model1).to eq(model2)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when the models have very different attributes' do
|
123
|
+
it do
|
124
|
+
expect(model1).to eq(model2)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when the attributes is missing just one attribute' do
|
130
|
+
let(:attributes) { %i[name] }
|
131
|
+
|
132
|
+
context 'when they are different classes and attributes are the same' do
|
133
|
+
let(:model2_class) { Class.new(model1_class) }
|
134
|
+
let(:name2) { name1 }
|
135
|
+
let(:age2) { age1 }
|
136
|
+
|
137
|
+
it do
|
138
|
+
expect(model1).not_to eq(model2)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when the models have a non listed different attribute' do
|
143
|
+
let(:name2) { name1 }
|
144
|
+
|
145
|
+
it do
|
146
|
+
expect(model1).to eq(model2)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when the models have a listed different attribute' do
|
151
|
+
let(:age2) { age1 }
|
152
|
+
|
153
|
+
it do
|
154
|
+
expect(model1).not_to eq(model2)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'when the models have very different attributes' do
|
159
|
+
it do
|
160
|
+
expect(model1).not_to eq(model2)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'when all attributes are included' do
|
166
|
+
let(:attributes) { %i[name age] }
|
167
|
+
|
168
|
+
context 'when they are different classes and attributes are the same' do
|
169
|
+
let(:model2_class) { Class.new(model1_class) }
|
170
|
+
let(:name2) { name1 }
|
171
|
+
let(:age2) { age1 }
|
172
|
+
|
173
|
+
it do
|
174
|
+
expect(model1).not_to eq(model2)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when the models have the same attributes' do
|
179
|
+
let(:name2) { name1 }
|
180
|
+
let(:age2) { age1 }
|
181
|
+
|
182
|
+
it do
|
183
|
+
expect(model1).to eq(model2)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'when the models have a listed different attribute' do
|
188
|
+
let(:name) { name1 }
|
189
|
+
|
190
|
+
it do
|
191
|
+
expect(model1).not_to eq(model2)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when the models have very different attributes' do
|
196
|
+
it do
|
197
|
+
expect(model1).not_to eq(model2)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::EqualsChecker do
|
6
|
+
subject(:checker) { described_class.new(attributes) }
|
7
|
+
|
8
|
+
let(:attributes) { %i[] }
|
9
|
+
|
10
|
+
let(:model1_class) { SampleModel }
|
11
|
+
let(:model2_class) { SampleModel }
|
12
|
+
let(:model1) { model1_class.new(**model1_attributes) }
|
13
|
+
let(:model2) { model2_class.new(**model2_attributes) }
|
14
|
+
|
15
|
+
let(:model1_attributes) { { name: name1, age: age1 } }
|
16
|
+
let(:model2_attributes) { { name: name2, age: age2 } }
|
17
|
+
let(:name1) { SecureRandom.hex(10) }
|
18
|
+
let(:name2) { SecureRandom.hex(10) }
|
19
|
+
let(:age1) { Random.rand(10..20) }
|
20
|
+
let(:age2) { Random.rand(21..50) }
|
21
|
+
|
22
|
+
describe 'match?' do
|
23
|
+
context 'when the attributes is empty' do
|
24
|
+
context 'when they are different classes and attributes are the same' do
|
25
|
+
let(:model2_class) { Class.new(SampleModel) }
|
26
|
+
let(:name2) { name1 }
|
27
|
+
let(:age2) { age1 }
|
28
|
+
|
29
|
+
it do
|
30
|
+
expect(checker).not_to be_match(model1, model2)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when the models have the same attributes' do
|
35
|
+
let(:name2) { name1 }
|
36
|
+
let(:age2) { age1 }
|
37
|
+
|
38
|
+
it do
|
39
|
+
expect(checker).to be_match(model1, model2)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when the models have very different attributes' do
|
44
|
+
it do
|
45
|
+
expect(checker).to be_match(model1, model2)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when the attributes is missing just one attribute' do
|
51
|
+
let(:attributes) { %i[name] }
|
52
|
+
|
53
|
+
context 'when they are different classes and attributes are the same' do
|
54
|
+
let(:model2_class) { Class.new(SampleModel) }
|
55
|
+
let(:name2) { name1 }
|
56
|
+
let(:age2) { age1 }
|
57
|
+
|
58
|
+
it do
|
59
|
+
expect(checker).not_to be_match(model1, model2)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when the models have a non listed different attribute' do
|
64
|
+
let(:name2) { name1 }
|
65
|
+
|
66
|
+
it do
|
67
|
+
expect(checker).to be_match(model1, model2)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when the models have a listed different attribute' do
|
72
|
+
let(:age2) { age1 }
|
73
|
+
|
74
|
+
it do
|
75
|
+
expect(checker).not_to be_match(model1, model2)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when the models have very different attributes' do
|
80
|
+
it do
|
81
|
+
expect(checker).not_to be_match(model1, model2)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when all attributes are included' do
|
87
|
+
let(:attributes) { %i[name age] }
|
88
|
+
|
89
|
+
context 'when they are different classes and attributes are the same' do
|
90
|
+
let(:model2_class) { Class.new(SampleModel) }
|
91
|
+
let(:name2) { name1 }
|
92
|
+
let(:age2) { age1 }
|
93
|
+
|
94
|
+
it do
|
95
|
+
expect(checker).not_to be_match(model1, model2)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when the models have the same attributes' do
|
100
|
+
let(:name2) { name1 }
|
101
|
+
let(:age2) { age1 }
|
102
|
+
|
103
|
+
it do
|
104
|
+
expect(checker).to be_match(model1, model2)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when the models have a listed different attribute' do
|
109
|
+
let(:name) { name1 }
|
110
|
+
|
111
|
+
it do
|
112
|
+
expect(checker).not_to be_match(model1, model2)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when the models have very different attributes' do
|
117
|
+
it do
|
118
|
+
expect(checker).not_to be_match(model1, model2)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#add' do
|
125
|
+
let(:attributes) { [:name] }
|
126
|
+
let(:new_attributes) { [:age] }
|
127
|
+
|
128
|
+
context 'when the new field has different values' do
|
129
|
+
let(:name2) { name1 }
|
130
|
+
|
131
|
+
it 'uses the new field to the match' do
|
132
|
+
expect { checker.add(new_attributes) }
|
133
|
+
.to change { checker.match?(model1, model2) }
|
134
|
+
.from(true).to(false)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when the old field has different values' do
|
139
|
+
let(:age2) { age1 }
|
140
|
+
|
141
|
+
it 'uses the new field to the match' do
|
142
|
+
expect { checker.add(new_attributes) }
|
143
|
+
.not_to change { checker.match?(model1, model2) }
|
144
|
+
.from(false)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodBuilder::CallMethodBuilder do
|
6
|
+
describe '#build' do
|
7
|
+
subject(:builder) do
|
8
|
+
described_class.new(klass, definition, type: type)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:call_name) { "attr_#{accessor_type}" }
|
12
|
+
|
13
|
+
let(:definition) do
|
14
|
+
Sinclair::MethodDefinition::CallDefinition.new(call_name, *attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when method called is attr_accessor' do
|
18
|
+
let(:accessor_type) { :accessor }
|
19
|
+
|
20
|
+
it_behaves_like 'a method builder that adds attribute reader'
|
21
|
+
it_behaves_like 'a method builder that adds attribute writer'
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when method called is attr_reader' do
|
25
|
+
let(:accessor_type) { :reader }
|
26
|
+
|
27
|
+
it_behaves_like 'a method builder that adds attribute reader' do
|
28
|
+
context 'when type is instance' do
|
29
|
+
let(:type) { Sinclair::MethodBuilder::INSTANCE_METHOD }
|
30
|
+
|
31
|
+
it 'does not add a reader' do
|
32
|
+
expect { builder.build }
|
33
|
+
.not_to add_method("#{method_name}=")
|
34
|
+
.to(instance)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when type is class' do
|
39
|
+
let(:type) { Sinclair::MethodBuilder::CLASS_METHOD }
|
40
|
+
|
41
|
+
it 'does not add a reader' do
|
42
|
+
expect { builder.build }
|
43
|
+
.not_to add_class_method("#{method_name}=")
|
44
|
+
.to(klass)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when method called is attr_writter' do
|
51
|
+
let(:accessor_type) { :writer }
|
52
|
+
|
53
|
+
it_behaves_like 'a method builder that adds attribute writer' do
|
54
|
+
context 'when type is instance' do
|
55
|
+
let(:type) { Sinclair::MethodBuilder::INSTANCE_METHOD }
|
56
|
+
|
57
|
+
it 'does not add a reader' do
|
58
|
+
expect { builder.build }
|
59
|
+
.not_to add_method(method_name)
|
60
|
+
.to(instance)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when type is class' do
|
65
|
+
let(:type) { Sinclair::MethodBuilder::CLASS_METHOD }
|
66
|
+
|
67
|
+
it 'does not add a reader' do
|
68
|
+
expect { builder.build }
|
69
|
+
.not_to add_class_method(method_name)
|
70
|
+
.to(klass)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -11,41 +11,84 @@ describe Sinclair::MethodBuilder do
|
|
11
11
|
let(:method_name) { :the_method }
|
12
12
|
let(:instance) { klass.new }
|
13
13
|
|
14
|
-
before do
|
15
|
-
definitions.add(method_name, value.to_s)
|
16
|
-
end
|
17
|
-
|
18
14
|
describe '#build_methods' do
|
19
|
-
context 'when
|
20
|
-
|
15
|
+
context 'when the method is a string definition' do
|
16
|
+
before do
|
17
|
+
definitions.add(method_name, value.to_s)
|
18
|
+
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
context 'when building an instance method' do
|
21
|
+
let(:type) { described_class::INSTANCE_METHOD }
|
22
|
+
|
23
|
+
it do
|
24
|
+
expect { builder.build_methods(definitions, type) }
|
25
|
+
.to add_method(method_name).to(instance)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the method is called' do
|
29
|
+
before { builder.build_methods(definitions, type) }
|
30
|
+
|
31
|
+
it do
|
32
|
+
expect(instance.the_method).to eq(value)
|
33
|
+
end
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
|
-
context 'when
|
28
|
-
|
37
|
+
context 'when building a class method' do
|
38
|
+
let(:type) { described_class::CLASS_METHOD }
|
29
39
|
|
30
40
|
it do
|
31
|
-
expect(
|
41
|
+
expect { builder.build_methods(definitions, type) }
|
42
|
+
.to add_class_method(method_name).to(klass)
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when the method is called' do
|
46
|
+
before { builder.build_methods(definitions, type) }
|
47
|
+
|
48
|
+
it do
|
49
|
+
expect(klass.the_method).to eq(value)
|
50
|
+
end
|
32
51
|
end
|
33
52
|
end
|
34
53
|
end
|
35
54
|
|
36
|
-
context 'when
|
37
|
-
|
55
|
+
context 'when the method is a block definition' do
|
56
|
+
before do
|
57
|
+
result = value
|
58
|
+
definitions.add(method_name) { result }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when building an instance method' do
|
62
|
+
let(:type) { described_class::INSTANCE_METHOD }
|
63
|
+
|
64
|
+
it do
|
65
|
+
expect { builder.build_methods(definitions, type) }
|
66
|
+
.to add_method(method_name).to(instance)
|
67
|
+
end
|
38
68
|
|
39
|
-
|
40
|
-
|
41
|
-
|
69
|
+
context 'when the method is called' do
|
70
|
+
before { builder.build_methods(definitions, type) }
|
71
|
+
|
72
|
+
it do
|
73
|
+
expect(instance.the_method).to eq(value)
|
74
|
+
end
|
75
|
+
end
|
42
76
|
end
|
43
77
|
|
44
|
-
context 'when
|
45
|
-
|
78
|
+
context 'when building a class method' do
|
79
|
+
let(:type) { described_class::CLASS_METHOD }
|
46
80
|
|
47
81
|
it do
|
48
|
-
expect(
|
82
|
+
expect { builder.build_methods(definitions, type) }
|
83
|
+
.to add_class_method(method_name).to(klass)
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when the method is called' do
|
87
|
+
before { builder.build_methods(definitions, type) }
|
88
|
+
|
89
|
+
it do
|
90
|
+
expect(klass.the_method).to eq(value)
|
91
|
+
end
|
49
92
|
end
|
50
93
|
end
|
51
94
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodDefinition::CallDefinition do
|
6
|
+
subject(:definition) do
|
7
|
+
described_class.new(call_name, *attributes)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:call_name) { :method_call }
|
11
|
+
let(:attributes) { %i[key1 value2] }
|
12
|
+
|
13
|
+
describe '#code_string' do
|
14
|
+
let(:expected) { 'method_call :key1, :value2' }
|
15
|
+
|
16
|
+
it 'returns the code string' do
|
17
|
+
expect(definition.code_string)
|
18
|
+
.to eq(expected)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#class_code_string' do
|
23
|
+
let(:expected) do
|
24
|
+
<<-RUBY
|
25
|
+
class << self
|
26
|
+
method_call :key1, :value2
|
27
|
+
end
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns the code string' do
|
32
|
+
expect(definition.class_code_string.gsub(/^ */, ''))
|
33
|
+
.to eq(expected.gsub(/^ */, ''))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|