sinclair 1.10.0 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/README.md +444 -324
- data/config/check_specs.yml +5 -5
- data/config/yardstick.yml +4 -0
- data/lib/sinclair/matchers/add_class_method.rb +0 -1
- data/lib/sinclair/method_builder/base.rb +32 -2
- data/lib/sinclair/method_builder/block_method_builder.rb +1 -12
- data/lib/sinclair/method_builder/call_method_builder.rb +10 -27
- data/lib/sinclair/method_builder/string_method_builder.rb +2 -29
- data/lib/sinclair/method_builder.rb +4 -20
- data/lib/sinclair/method_definition/block_definition.rb +2 -0
- data/lib/sinclair/method_definition/call_definition.rb +15 -18
- data/lib/sinclair/method_definition/parameter_builder.rb +89 -0
- data/lib/sinclair/method_definition/parameter_helper.rb +124 -0
- data/lib/sinclair/method_definition/string_definition.rb +26 -2
- data/lib/sinclair/method_definition.rb +42 -3
- data/lib/sinclair/method_definitions.rb +20 -22
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +149 -62
- data/spec/integration/readme/sinclair/types_of_definition_spec.rb +61 -0
- data/spec/integration/yard/sinclair/add_class_method_spec.rb +51 -0
- data/spec/integration/yard/sinclair/add_method_spec.rb +60 -0
- data/spec/integration/yard/sinclair/eval_and_add_method_spec.rb +26 -0
- data/spec/integration/yard/sinclair_spec.rb +0 -83
- data/spec/lib/sinclair/method_builder/base_spec.rb +15 -0
- data/spec/lib/sinclair/method_builder/string_method_builder_spec.rb +24 -1
- data/spec/lib/sinclair/method_definition/call_definition_spec.rb +14 -17
- data/spec/lib/sinclair/method_definition/parameter_builder_spec.rb +81 -0
- data/spec/lib/sinclair/method_definition/string_definition_spec.rb +60 -29
- data/spec/lib/sinclair/method_definition_spec.rb +77 -2
- data/spec/lib/sinclair/method_definitions_spec.rb +15 -16
- data/spec/lib/sinclair_spec.rb +6 -160
- data/spec/support/models/dummy_builder.rb +5 -1
- data/spec/support/models/dummy_class_builder.rb +4 -0
- data/spec/support/models/person.rb +1 -1
- data/spec/support/shared_examples/sinclair.rb +118 -0
- metadata +11 -2
@@ -12,37 +12,35 @@ class Sinclair
|
|
12
12
|
#
|
13
13
|
# The type is decided based in the arguments
|
14
14
|
#
|
15
|
-
# @param name [String,Symbol] method name
|
16
|
-
# @param options [Hash] Options of construction
|
17
|
-
# @option options cached [Boolean] Flag telling to create
|
18
|
-
# a method with cache
|
19
|
-
#
|
20
15
|
# @overload add(definition_class, name, code = nil, **options)
|
16
|
+
# @param name [String,Symbol] method name
|
21
17
|
# @param code [String] code to be evaluated when the method is ran
|
18
|
+
# @param options [Hash] Options of construction
|
19
|
+
# @option options cached [Boolean] Flag telling to create
|
20
|
+
# a method with cache
|
22
21
|
#
|
23
22
|
# @overload add(definition_class, name, **options, &block)
|
23
|
+
# @param name [String,Symbol] method name
|
24
|
+
# @param options [Hash] Options of construction
|
25
|
+
# @option options cached [Boolean] Flag telling to create
|
26
|
+
# a method with cache
|
24
27
|
# @param block [Proc] block to be ran as method
|
25
28
|
#
|
26
|
-
# @
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
29
|
+
# @overload add(type, *args, **options, &block)
|
30
|
+
# @param type [Symbol] type of definition
|
31
|
+
# - :string -> {MethodDefinition::StringDefinition}
|
32
|
+
# - :block -> {MethodDefinition::BlockDefinition}
|
33
|
+
# - :call -> {MethodDefinition::CallDefinition}
|
34
|
+
# @param options [Hash] Options of construction
|
35
|
+
# @option options cached [Boolean] Flag telling to create
|
36
|
+
# a method with cache
|
37
|
+
# @param block [Proc] block to be ran as method
|
34
38
|
#
|
35
|
-
# @
|
36
|
-
#
|
37
|
-
# - :block -> {MethodDefinition::BlockDefinition}
|
38
|
-
# - :call -> {MethodDefinition::CallDefinition}
|
39
|
-
# @param options [Hash] Options of construction
|
40
|
-
# @option options cached [Boolean] Flag telling to create
|
41
|
-
# a method with cache
|
42
|
-
# @param block [Proc] block to be ran as method
|
39
|
+
# @see MethodDefinition.for
|
40
|
+
# @see MethodDefinition.from
|
43
41
|
#
|
44
42
|
# @return [Array<MethodDefinition>]
|
45
|
-
def
|
43
|
+
def add(*args, type: nil, **options, &block)
|
46
44
|
definitions << MethodDefinition.for(type, *args, **options, &block)
|
47
45
|
end
|
48
46
|
|
data/lib/sinclair/version.rb
CHANGED
data/lib/sinclair.rb
CHANGED
@@ -179,107 +179,193 @@ class Sinclair
|
|
179
179
|
end
|
180
180
|
|
181
181
|
# Add a method to the method list to be created on klass instances
|
182
|
-
#
|
183
|
-
# @param name [String,Symbol] name of the method to be added
|
184
|
-
# @param options [Hash] Options of construction
|
185
|
-
# @option options cached [Boolean] Flag telling to create
|
186
|
-
# a method with cache
|
182
|
+
# @see MethodDefinitions#add
|
187
183
|
#
|
188
184
|
# @overload add_method(name, code, **options)
|
185
|
+
# @param name [String,Symbol] name of the method to be added
|
189
186
|
# @param code [String] code to be evaluated when the method is ran
|
187
|
+
# @param options [Hash] Options of construction
|
188
|
+
# @option options cached [Boolean] Flag telling to create
|
189
|
+
# a method with cache
|
190
|
+
# @see MethodDefinition::StringDefinition
|
191
|
+
#
|
192
|
+
# @example Using string code to add a string defined method
|
193
|
+
# class Person
|
194
|
+
# attr_accessor :first_name, :last_name
|
195
|
+
#
|
196
|
+
# def initialize(first_name, last_name)
|
197
|
+
# @first_name = first_name
|
198
|
+
# @last_name = last_name
|
199
|
+
# end
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# builder = Sinclair.new(Person)
|
203
|
+
# builder.add_method(:full_name, '[first_name, last_name].join(" ")')
|
204
|
+
# builder.build
|
205
|
+
#
|
206
|
+
# Person.new('john', 'wick').full_name # returns 'john wick'
|
190
207
|
#
|
191
208
|
# @overload add_method(name, **options, &block)
|
209
|
+
# @param name [String,Symbol] name of the method to be added
|
192
210
|
# @param block [Proc] block to be ran as method
|
211
|
+
# @param options [Hash] Options of construction
|
212
|
+
# @option options cached [Boolean] Flag telling to create
|
213
|
+
# a method with cache
|
214
|
+
# @see MethodDefinition::BlockDefinition
|
215
|
+
#
|
216
|
+
# @example Using block to add a block method
|
217
|
+
# class Person
|
218
|
+
# attr_accessor :first_name, :last_name
|
219
|
+
#
|
220
|
+
# def initialize(first_name, last_name)
|
221
|
+
# @first_name = first_name
|
222
|
+
# @last_name = last_name
|
223
|
+
# end
|
224
|
+
# end
|
193
225
|
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
226
|
+
# builder = Sinclair.new(Person)
|
227
|
+
# builder.add_method(:bond_name) { "#{last_name}, #{first_name} #{last_name}" }
|
228
|
+
# builder.build
|
229
|
+
#
|
230
|
+
# Person.new('john', 'wick').bond_name # returns 'wick, john wick'
|
231
|
+
#
|
232
|
+
# @overload add_method(*args, type:, **options, &block)
|
233
|
+
# @param args [Array<Object>] arguments to be passed to the definition
|
234
|
+
# @param type [Symbol] type of method definition
|
235
|
+
# @param block [Proc] block to be ran as method when type is block
|
236
|
+
# @param options [Hash] Options of construction
|
237
|
+
# @option options cached [Boolean] Flag telling to create
|
238
|
+
# a method with cache
|
239
|
+
# @see MethodDefinition::BlockDefinition
|
240
|
+
# @see MethodDefinition::StringDefinition
|
241
|
+
# @see MethodDefinition::CallDefinition
|
242
|
+
#
|
243
|
+
# @example Passing type block
|
244
|
+
# class Person
|
245
|
+
# attr_accessor :first_name, :last_name
|
246
|
+
#
|
247
|
+
# def initialize(first_name, last_name)
|
248
|
+
# @first_name = first_name
|
249
|
+
# @last_name = last_name
|
250
|
+
# end
|
201
251
|
# end
|
202
|
-
# end
|
203
252
|
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
253
|
+
# builder = Sinclair.new(Person)
|
254
|
+
# builder.add_method(:bond_name, type: :block, cached: true) do
|
255
|
+
# "{last_name}, #{first_name} #{last_name}"
|
256
|
+
# end
|
257
|
+
# builder.build
|
207
258
|
#
|
208
|
-
#
|
259
|
+
# person.Person.new('john', 'wick')
|
209
260
|
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
261
|
+
# person.bond_name # returns 'wick, john wick'
|
262
|
+
# person.first_name = 'Johny'
|
263
|
+
# person.bond_name # returns 'wick, john wick'
|
213
264
|
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
# @last_name = last_name
|
265
|
+
# @example Passing type call
|
266
|
+
# class Person
|
217
267
|
# end
|
218
|
-
# end
|
219
268
|
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
# builder.build
|
269
|
+
# builder = Sinclair.new(Person)
|
270
|
+
# builder.add_method(:attr_accessor, :bond_name, type: :call)
|
271
|
+
# builder.build
|
224
272
|
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
)
|
273
|
+
# person.bond_name = 'Bond, James Bond'
|
274
|
+
# person.bond_name # returns 'Bond, James Bond'
|
275
|
+
#
|
276
|
+
# @return [Array<MethodDefinition>] the list of all currently defined instance methods
|
277
|
+
def add_method(*args, type: nil, **options, &block)
|
278
|
+
definitions.add(*args, type: type, **options, &block)
|
231
279
|
end
|
232
280
|
|
233
281
|
# Add a method to the method list to be created on klass
|
234
|
-
#
|
235
|
-
# @param name [String,Symbol] name of the method to be added
|
236
|
-
# @param options [Hash] Options of construction
|
237
|
-
# @option options cached [Boolean] Flag telling to create
|
238
|
-
# a method with cache
|
282
|
+
# @see MethodDefinitions#add
|
239
283
|
#
|
240
284
|
# @overload add_class_method(name, code, **options)
|
285
|
+
# @param name [String,Symbol] name of the method to be added
|
241
286
|
# @param code [String] code to be evaluated when the method is ran
|
287
|
+
# @param options [Hash] Options of construction
|
288
|
+
# @option options cached [Boolean] Flag telling to create
|
289
|
+
# a method with cache
|
290
|
+
#
|
291
|
+
# @example Adding a method by String
|
292
|
+
# class EnvFetcher
|
293
|
+
# end
|
294
|
+
#
|
295
|
+
# builder = Sinclair.new(EnvFetcher)
|
296
|
+
#
|
297
|
+
# builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
|
298
|
+
# builder.build
|
299
|
+
#
|
300
|
+
# ENV['HOSTNAME'] = 'myhost'
|
301
|
+
#
|
302
|
+
# EnvFetcher.hostname # returns 'myhost'
|
242
303
|
#
|
243
304
|
# @overload add_class_method(name, **options, &block)
|
305
|
+
# @param name [String,Symbol] name of the method to be added
|
244
306
|
# @param block [Proc] block to be ran as method
|
307
|
+
# @param options [Hash] Options of construction
|
308
|
+
# @option options cached [Boolean] Flag telling to create
|
309
|
+
# a method with cache
|
245
310
|
#
|
246
|
-
#
|
247
|
-
#
|
248
|
-
#
|
311
|
+
# @example Adding a method by Block
|
312
|
+
# class EnvFetcher
|
313
|
+
# end
|
249
314
|
#
|
250
|
-
#
|
315
|
+
# builder = Sinclair.new(EnvFetcher)
|
251
316
|
#
|
252
|
-
#
|
253
|
-
#
|
317
|
+
# builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
|
318
|
+
# builder.build
|
254
319
|
#
|
255
|
-
#
|
320
|
+
# ENV['TIMEOUT'] = '300'
|
256
321
|
#
|
257
|
-
#
|
322
|
+
# EnvFetcher.timeout # returns '300'
|
258
323
|
#
|
259
|
-
# @
|
260
|
-
#
|
261
|
-
#
|
324
|
+
# @overload add_class_method(*args, type: **options, &block)
|
325
|
+
# @param args [Array<Object>] arguments to be passed to the definition
|
326
|
+
# @param type [Symbol] type of method definition
|
327
|
+
# @param block [Proc] block to be ran as method when type is block
|
328
|
+
# @param options [Hash] Options of construction
|
329
|
+
# @option options cached [Boolean] Flag telling to create
|
330
|
+
# a method with cache
|
331
|
+
# @see MethodDefinition::BlockDefinition
|
332
|
+
# @see MethodDefinition::StringDefinition
|
333
|
+
# @see MethodDefinition::CallDefinition
|
262
334
|
#
|
263
|
-
#
|
335
|
+
# @example Passing type block
|
336
|
+
# class EnvFetcher
|
337
|
+
# end
|
264
338
|
#
|
265
|
-
#
|
266
|
-
# builder.build
|
339
|
+
# builder = Sinclair.new(EnvFetcher)
|
267
340
|
#
|
268
|
-
#
|
341
|
+
# builder.add_class_method(:timeout, type: :block) { ENV['TIMEOUT'] }
|
342
|
+
# builder.build
|
269
343
|
#
|
270
|
-
#
|
344
|
+
# ENV['TIMEOUT'] = '300'
|
271
345
|
#
|
272
|
-
#
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
346
|
+
# EnvFetcher.timeout # returns '300'
|
347
|
+
#
|
348
|
+
# @example Passing type call
|
349
|
+
# class EnvFetcher
|
350
|
+
# end
|
351
|
+
#
|
352
|
+
# builder = Sinclair.new(EnvFetcher)
|
353
|
+
#
|
354
|
+
# builder.add_class_method(:attr_accessor, :timeout, type: :call)
|
355
|
+
# builder.build
|
356
|
+
#
|
357
|
+
# EnvFetcher.timeout = 10
|
358
|
+
#
|
359
|
+
# env_fetcher.timeout # returns '10'
|
360
|
+
#
|
361
|
+
# @return [Array<MethodDefinition>] the list of all currently defined class methods
|
362
|
+
def add_class_method(*args, type: nil, **options, &block)
|
363
|
+
class_definitions.add(*args, type: type, **options, &block)
|
277
364
|
end
|
278
365
|
|
279
366
|
# Evaluetes a block which will result in a String, the method code
|
280
367
|
#
|
281
368
|
# @example Building a initial value class method
|
282
|
-
#
|
283
369
|
# module InitialValuer
|
284
370
|
# extend ActiveSupport::Concern
|
285
371
|
#
|
@@ -301,6 +387,7 @@ class Sinclair
|
|
301
387
|
# end
|
302
388
|
#
|
303
389
|
# object = MyClass.new
|
390
|
+
#
|
304
391
|
# object.age # 20
|
305
392
|
# object.age = 30
|
306
393
|
# object.age # 30
|
@@ -345,7 +432,7 @@ class Sinclair
|
|
345
432
|
# end
|
346
433
|
#
|
347
434
|
# Purchase.new(2.3, 5).total_price # returns 11.5
|
348
|
-
# @return [Array<MethodDefinition>]
|
435
|
+
# @return [Array<MethodDefinition>] the list of all currently defined instance methods
|
349
436
|
def eval_and_add_method(name, &block)
|
350
437
|
add_method(name, instance_eval(&block))
|
351
438
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair do
|
6
|
+
describe 'README' do
|
7
|
+
describe 'Define method using block' do
|
8
|
+
it 'adds the method' do
|
9
|
+
klass = Class.new
|
10
|
+
instance = klass.new
|
11
|
+
|
12
|
+
builder = described_class.new(klass)
|
13
|
+
builder.add_method(:random_number) { Random.rand(10..20) }
|
14
|
+
builder.build
|
15
|
+
|
16
|
+
expect(instance.random_number).to be_between(10, 20)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'Define method using string' do
|
21
|
+
it 'adds the method' do
|
22
|
+
klass = Class.new
|
23
|
+
instance = klass.new
|
24
|
+
|
25
|
+
builder = described_class.new(klass)
|
26
|
+
builder.add_method(:random_number, 'Random.rand(10..20)')
|
27
|
+
builder.build
|
28
|
+
|
29
|
+
expect(instance.random_number).to be_between(10, 20)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'Define method using string with parameters' do
|
34
|
+
it 'adds the method' do
|
35
|
+
klass = Class.new
|
36
|
+
|
37
|
+
builder = described_class.new(klass)
|
38
|
+
builder.add_class_method(
|
39
|
+
:function, 'a ** b + c', parameters: [:a], named_parameters: [:b, { c: 15 }]
|
40
|
+
)
|
41
|
+
builder.build
|
42
|
+
|
43
|
+
expect(klass.function(10, b: 2)).to eq(115)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'Define method using call to the class' do
|
48
|
+
it 'performs the call to the class' do
|
49
|
+
klass = Class.new
|
50
|
+
|
51
|
+
builder = described_class.new(klass)
|
52
|
+
builder.add_class_method(:attr_accessor, :number, type: :call)
|
53
|
+
builder.build
|
54
|
+
|
55
|
+
expect(klass.number).to be_nil
|
56
|
+
klass.number = 10
|
57
|
+
expect(klass.number).to eq(10)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair#add_class_method' do
|
6
|
+
let(:klass) { Class.new }
|
7
|
+
|
8
|
+
describe 'Adding a method by String' do
|
9
|
+
it 'returns the hostname' do
|
10
|
+
builder = Sinclair.new(klass)
|
11
|
+
builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
|
12
|
+
builder.build
|
13
|
+
ENV['HOSTNAME'] = 'myhost'
|
14
|
+
|
15
|
+
expect(klass.hostname).to eq('myhost')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'Adding a method by Block' do
|
20
|
+
it 'returns the timeout' do
|
21
|
+
builder = Sinclair.new(klass)
|
22
|
+
builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
|
23
|
+
builder.build
|
24
|
+
ENV['TIMEOUT'] = '300'
|
25
|
+
|
26
|
+
expect(klass.timeout).to eq('300')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'Passing type block' do
|
31
|
+
it 'creates new method' do
|
32
|
+
builder = Sinclair.new(klass)
|
33
|
+
builder.add_class_method(:timeout, type: :block) { ENV['TIMEOUT'] }
|
34
|
+
builder.build
|
35
|
+
ENV['TIMEOUT'] = '300'
|
36
|
+
|
37
|
+
expect(klass.timeout).to eq('300')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'Passing type call' do
|
42
|
+
it 'creates new method' do
|
43
|
+
builder = Sinclair.new(klass)
|
44
|
+
builder.add_class_method(:attr_accessor, :timeout, type: :call)
|
45
|
+
builder.build
|
46
|
+
|
47
|
+
klass.timeout = 10
|
48
|
+
expect(klass.timeout).to eq(10)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair#add_method' do
|
6
|
+
describe 'Using string code to add a string defined method' do
|
7
|
+
let(:klass) { Class.new(Person) }
|
8
|
+
|
9
|
+
it 'creates new method' do
|
10
|
+
builder = Sinclair.new(klass)
|
11
|
+
builder.add_method(:full_name, '[first_name, last_name].join(" ")')
|
12
|
+
builder.build
|
13
|
+
|
14
|
+
expect(klass.new('john', 'wick').full_name).to eq('john wick')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Using block to add a block method' do
|
19
|
+
let(:klass) { Class.new(Person) }
|
20
|
+
|
21
|
+
it 'creates new method' do
|
22
|
+
builder = Sinclair.new(klass)
|
23
|
+
builder.add_method(:bond_name) { "#{last_name}, #{first_name} #{last_name}" }
|
24
|
+
builder.build
|
25
|
+
|
26
|
+
expect(klass.new('john', 'wick').bond_name).to eq('wick, john wick')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'Passing type block' do
|
31
|
+
let(:klass) { Class.new(Person) }
|
32
|
+
|
33
|
+
it 'creates new method' do
|
34
|
+
builder = Sinclair.new(klass)
|
35
|
+
builder.add_method(:bond_name, type: :block, cached: true) do
|
36
|
+
"#{last_name}, #{first_name} #{last_name}"
|
37
|
+
end
|
38
|
+
builder.build
|
39
|
+
person = klass.new('john', 'wick')
|
40
|
+
|
41
|
+
expect(person.bond_name).to eq('wick, john wick')
|
42
|
+
person.first_name = 'Johny'
|
43
|
+
expect(person.bond_name).to eq('wick, john wick')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'Passing type call' do
|
48
|
+
let(:klass) { Class.new }
|
49
|
+
|
50
|
+
it 'creates new method' do
|
51
|
+
builder = Sinclair.new(klass)
|
52
|
+
builder.add_method(:attr_accessor, :bond_name, type: :call)
|
53
|
+
builder.build
|
54
|
+
person = klass.new
|
55
|
+
|
56
|
+
person.bond_name = 'Bond, James Bond'
|
57
|
+
expect(person.bond_name).to eq('Bond, James Bond')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair#eval_and_add_method' do
|
6
|
+
describe 'Building a initial value class method' do
|
7
|
+
let(:klass) do
|
8
|
+
Class.new do
|
9
|
+
include InitialValuer
|
10
|
+
attr_writer :age
|
11
|
+
|
12
|
+
initial_value_for :age, 20
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when it has not been initialized' do
|
17
|
+
it do
|
18
|
+
object = klass.new
|
19
|
+
|
20
|
+
expect(object.age).to eq(20)
|
21
|
+
object.age = 30
|
22
|
+
expect(object.age).to eq(30)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -119,88 +119,5 @@ describe Sinclair do
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
122
|
-
|
123
|
-
describe '#add_method' do
|
124
|
-
let(:klass) { Class.new(Person) }
|
125
|
-
let(:instance) { klass.new('john', 'wick') }
|
126
|
-
|
127
|
-
before do
|
128
|
-
builder.add_method(:full_name, '[first_name, last_name].join(" ")')
|
129
|
-
builder.add_method(:bond_name) { "#{last_name}, #{first_name} #{last_name}" }
|
130
|
-
builder.build
|
131
|
-
end
|
132
|
-
|
133
|
-
describe '#full_name' do
|
134
|
-
it 'returns the full name' do
|
135
|
-
expect(instance.full_name).to eq('john wick')
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
describe '#bond_name' do
|
140
|
-
it 'returns the full name, bond style' do
|
141
|
-
expect(instance.bond_name).to eq('wick, john wick')
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe '#add_class_method' do
|
147
|
-
let(:klass) { env_fetcher }
|
148
|
-
let(:env_fetcher) { Class.new }
|
149
|
-
|
150
|
-
describe '#hostname' do
|
151
|
-
before do
|
152
|
-
builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
|
153
|
-
builder.build
|
154
|
-
ENV['HOSTNAME'] = 'myhost'
|
155
|
-
end
|
156
|
-
|
157
|
-
it 'returns the hostname' do
|
158
|
-
expect(env_fetcher.hostname).to eq('myhost')
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
describe '#timeout' do
|
163
|
-
before do
|
164
|
-
builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
|
165
|
-
builder.build
|
166
|
-
ENV['TIMEOUT'] = '300'
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'returns the timeout' do
|
170
|
-
expect(env_fetcher.timeout).to eq('300')
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
describe '#eval_and_add_method' do
|
176
|
-
subject(:builder) { klass.new }
|
177
|
-
|
178
|
-
let(:klass) do
|
179
|
-
Class.new do
|
180
|
-
include InitialValuer
|
181
|
-
attr_writer :age
|
182
|
-
initial_value_for :age, 20
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
describe '#age' do
|
187
|
-
context 'when it has not been initialized' do
|
188
|
-
it do
|
189
|
-
expect(builder.age).to eq(20)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
context 'when it has been initialized' do
|
194
|
-
before do
|
195
|
-
builder.age
|
196
|
-
builder.age = 30
|
197
|
-
end
|
198
|
-
|
199
|
-
it do
|
200
|
-
expect(builder.age).to eq(30)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
122
|
end
|
206
123
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodBuilder::Base do
|
6
|
+
describe '.build' do
|
7
|
+
let(:klass) { Class.new }
|
8
|
+
let(:type) { Sinclair::MethodBuilder::CLASS_METHOD }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect { described_class.build(klass, instance_of(described_class), type: type) }
|
12
|
+
.to raise_error(NotImplementedError)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -12,9 +12,11 @@ describe Sinclair::MethodBuilder::StringMethodBuilder do
|
|
12
12
|
let(:instance) { klass.new }
|
13
13
|
let(:value) { Random.rand }
|
14
14
|
let(:method_name) { :the_method }
|
15
|
+
let(:code) { value.to_s }
|
16
|
+
let(:options) { {} }
|
15
17
|
|
16
18
|
let(:definition) do
|
17
|
-
Sinclair::MethodDefinition.from(method_name,
|
19
|
+
Sinclair::MethodDefinition.from(method_name, code, **options)
|
18
20
|
end
|
19
21
|
|
20
22
|
context 'when type is instance' do
|
@@ -31,6 +33,27 @@ describe Sinclair::MethodBuilder::StringMethodBuilder do
|
|
31
33
|
it 'returns the result of the code when called' do
|
32
34
|
expect(instance.the_method).to eq(value)
|
33
35
|
end
|
36
|
+
|
37
|
+
it 'creates a method with no parameters' do
|
38
|
+
expect(instance.method(method_name).parameters)
|
39
|
+
.to be_empty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when the method is built with parameters' do
|
44
|
+
let(:code) { 'a + b' }
|
45
|
+
let(:options) { { parameters: %i[a b] } }
|
46
|
+
|
47
|
+
before { builder.build }
|
48
|
+
|
49
|
+
it 'returns the result of the code when called' do
|
50
|
+
expect(instance.the_method(12, 23)).to eq(35)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'creates a method with no parameters' do
|
54
|
+
expect(instance.method(method_name).parameters)
|
55
|
+
.to eq([%i[req a], %i[req b]])
|
56
|
+
end
|
34
57
|
end
|
35
58
|
end
|
36
59
|
|