sinclair 1.9.0 → 1.11.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -1
  3. data/README.md +414 -324
  4. data/config/check_specs.yml +3 -4
  5. data/config/yardstick.yml +9 -1
  6. data/lib/sinclair/configurable.rb +2 -0
  7. data/lib/sinclair/equals_checker.rb +2 -0
  8. data/lib/sinclair/matchers/add_class_method.rb +26 -36
  9. data/lib/sinclair/matchers/add_instance_method.rb +59 -59
  10. data/lib/sinclair/matchers/add_method.rb +33 -35
  11. data/lib/sinclair/matchers/change_class_method.rb +22 -16
  12. data/lib/sinclair/matchers/change_instance_method.rb +46 -16
  13. data/lib/sinclair/matchers.rb +2 -8
  14. data/lib/sinclair/method_builder/base.rb +17 -2
  15. data/lib/sinclair/method_builder/call_method_builder.rb +49 -0
  16. data/lib/sinclair/method_builder.rb +5 -17
  17. data/lib/sinclair/method_definition/block_definition.rb +2 -0
  18. data/lib/sinclair/method_definition/call_definition.rb +49 -0
  19. data/lib/sinclair/method_definition/string_definition.rb +2 -2
  20. data/lib/sinclair/method_definition.rb +80 -26
  21. data/lib/sinclair/method_definitions.rb +25 -7
  22. data/lib/sinclair/options/builder.rb +8 -0
  23. data/lib/sinclair/options.rb +1 -13
  24. data/lib/sinclair/version.rb +1 -1
  25. data/lib/sinclair.rb +149 -62
  26. data/spec/integration/readme/sinclair/types_of_definition_spec.rb +47 -0
  27. data/spec/integration/yard/sinclair/add_class_method_spec.rb +51 -0
  28. data/spec/integration/yard/sinclair/add_method_spec.rb +60 -0
  29. data/spec/integration/yard/sinclair/eval_and_add_method_spec.rb +26 -0
  30. data/spec/integration/yard/sinclair/matchers/change_class_method_spec.rb +24 -0
  31. data/spec/integration/yard/sinclair/matchers/change_instance_method_spec.rb +40 -0
  32. data/spec/integration/yard/sinclair_spec.rb +0 -83
  33. data/spec/lib/sinclair/method_builder/base_spec.rb +15 -0
  34. data/spec/lib/sinclair/method_builder/call_method_builder_spec.rb +76 -0
  35. data/spec/lib/sinclair/method_builder_spec.rb +63 -20
  36. data/spec/lib/sinclair/method_definition/call_definition_spec.rb +33 -0
  37. data/spec/lib/sinclair/method_definition_spec.rb +129 -0
  38. data/spec/lib/sinclair/method_definitions_spec.rb +79 -1
  39. data/spec/lib/sinclair/options/builder_spec.rb +13 -0
  40. data/spec/lib/sinclair/options/class_methods_spec.rb +23 -8
  41. data/spec/lib/sinclair_spec.rb +6 -160
  42. data/spec/support/models/dummy_builder.rb +4 -1
  43. data/spec/support/models/dummy_class_builder.rb +3 -0
  44. data/spec/support/models/person.rb +1 -1
  45. data/spec/support/shared_examples/attribute_accessor.rb +103 -0
  46. data/spec/support/shared_examples/sinclair.rb +112 -0
  47. metadata +15 -2
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class MethodDefinition
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Define a call of method to e done within the class
9
+ class CallDefinition < MethodDefinition
10
+ build_with MethodBuilder::CallMethodBuilder
11
+
12
+ # @param method_name [Symbol] method to be called
13
+ # @param arguments [Array<Symbol,String>] parameters to be passed as
14
+ # arguments to the call
15
+ def initialize(method_name, *arguments)
16
+ @arguments = arguments
17
+ super(method_name)
18
+ end
19
+
20
+ default_value :block?, false
21
+ default_value :string?, false
22
+
23
+ # Block to be evaluated by the class when adding methods
24
+ #
25
+ # The block will be a call from +method_name+ passing +arguments+
26
+ # as arguments
27
+ # @return [Proc]
28
+ def code_block
29
+ method_name = name
30
+ args = arguments
31
+
32
+ proc do
33
+ send(method_name, *args)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :arguments
40
+ # @method arguments
41
+ # @api private
42
+ # @private
43
+ #
44
+ # Arguments to be passed when calling the method inside the block
45
+ #
46
+ # @return [Array<Object>]
47
+ end
48
+ end
49
+ end
@@ -5,10 +5,10 @@ class Sinclair
5
5
  # @api private
6
6
  # @author darthjee
7
7
  #
8
- # @abstract
9
- #
10
8
  # Define an instance method from string
11
9
  class StringDefinition < MethodDefinition
10
+ build_with MethodBuilder::StringMethodBuilder
11
+
12
12
  # @param name [String,Symbol] name of the method
13
13
  # @param code [String] code to be evaluated as method
14
14
  # @param options [Hash] Options of construction
@@ -12,6 +12,8 @@ class Sinclair
12
12
  autoload :BlockDefinition, 'sinclair/method_definition/block_definition'
13
13
  autoload :StringDefinition, 'sinclair/method_definition/string_definition'
14
14
 
15
+ autoload :CallDefinition, 'sinclair/method_definition/call_definition'
16
+
15
17
  # @method name
16
18
  #
17
19
  # name of the method
@@ -24,31 +26,80 @@ class Sinclair
24
26
  cached: false
25
27
  }.freeze
26
28
 
27
- # Builds a method that will return the same value always
28
- #
29
- # @return [Symbol]
30
- def self.default_value(method_name, value)
31
- define_method(method_name) { value }
32
- end
29
+ class << self
30
+ # Builds a method that will return the same value always
31
+ #
32
+ # @return [Symbol]
33
+ def default_value(method_name, value)
34
+ define_method(method_name) { value }
35
+ end
33
36
 
34
- # @param name [String,Symbol] name of the method
35
- # @param code [String] code to be evaluated as method
36
- # @param block [Proc] block with code to be added as method
37
- # @param options [Hash] Options of construction
38
- # @option options cached [Boolean] Flag telling to create a block
39
- # with cache
40
- #
41
- # builds a method definition based on arguments
42
- #
43
- # when block is given, returns a {BlockDefinition} and
44
- # returns a {StringDefinition} otherwise
45
- #
46
- # @return [Base]
47
- def self.from(name, code = nil, **options, &block)
48
- if block
49
- BlockDefinition.new(name, **options, &block)
50
- else
51
- StringDefinition.new(name, code, **options)
37
+ # @param name [String,Symbol] name of the method
38
+ # @param code [String] code to be evaluated as method
39
+ # @param block [Proc] block with code to be added as method
40
+ # @param options [Hash] Options of construction
41
+ # @option options cached [Boolean] Flag telling to create a block
42
+ # with cache
43
+ #
44
+ # builds a method definition based on arguments
45
+ #
46
+ # when block is given, returns a {BlockDefinition} and
47
+ # returns a {StringDefinition} otherwise
48
+ #
49
+ # @return [Base]
50
+ def from(name, code = nil, **options, &block)
51
+ if block
52
+ BlockDefinition.new(name, **options, &block)
53
+ else
54
+ StringDefinition.new(name, code, **options)
55
+ end
56
+ end
57
+
58
+ # creates a definition
59
+ #
60
+ # The creation is based on type which will be used to infer
61
+ # which subclass of {Sinclair::MethodDefinition} to be used
62
+ #
63
+ # If type is +nil+ then call is delegated to {.from} which will infer the type
64
+ # from the arguments
65
+ #
66
+ # @param type [Symbol] the method definition type
67
+ #
68
+ # @return [Sinclair::MethodDefinition] an instance of a subclass
69
+ def for(type, *args, **options, &block)
70
+ return from(*args, **options, &block) unless type
71
+
72
+ klass = const_get("#{type}_definition".camelize)
73
+ klass.new(*args, **options, &block)
74
+ end
75
+
76
+ # Defines builder for a definition class
77
+ #
78
+ # @param builder_class [Class<MethodBuilder>]
79
+ #
80
+ # @return [Symbol] constant +:build+
81
+ #
82
+ # @!macro build_with
83
+ # @api private
84
+ #
85
+ # @!method build(klass, type)
86
+ #
87
+ # Builds the method defined
88
+ #
89
+ # The method is built using {$1}
90
+ #
91
+ # @param klass [Class] The class where the method will be built
92
+ # @param type [Symbol] type of method to be built
93
+ # - {MethodBuilder::CLASS_METHOD} : A class method will be built
94
+ # - {MethodBuilder::INSTANCE_METHOD} : An instance method will be built
95
+ #
96
+ # @see $1#build
97
+ #
98
+ # @return [Symbol] the name of the method built
99
+ def build_with(builder_class)
100
+ define_method(:build) do |klass, type|
101
+ builder_class.build(klass, self, type: type)
102
+ end
52
103
  end
53
104
  end
54
105
 
@@ -71,10 +122,13 @@ class Sinclair
71
122
  #
72
123
  # @example (see MethodDefinition::StringDefinition#build)
73
124
  # @example (see MethodDefinition::BlockDefinition#build)
125
+ # @example (see MethodDefinition::CallDefinition#build)
74
126
  #
75
127
  # @return [Symbol] name of the created method
76
- def build(_klass)
77
- raise 'Build is implemented in subclasses. ' \
128
+ #
129
+ # @raise NotImplementedError
130
+ def build(_klass, _type)
131
+ raise NotImplementedError, 'Build is implemented in subclasses. ' \
78
132
  "Use #{self.class}.from to initialize a proper object"
79
133
  end
80
134
 
@@ -10,20 +10,38 @@ class Sinclair
10
10
 
11
11
  # Builds and adds new definition
12
12
  #
13
- # @param name [String,Symbol] method name
14
- # @param options [Hash] Options of construction
15
- # @option options cached [Boolean] Flag telling to create
16
- # a method with cache
13
+ # The type is decided based in the arguments
17
14
  #
18
15
  # @overload add(definition_class, name, code = nil, **options)
16
+ # @param name [String,Symbol] method name
19
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
20
21
  #
21
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
22
27
  # @param block [Proc] block to be ran as method
23
28
  #
24
- # @return MethodDefinitions
25
- def add(name, code = nil, **options, &block)
26
- definitions << MethodDefinition.from(name, code, **options, &block)
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
38
+ #
39
+ # @see MethodDefinition.for
40
+ # @see MethodDefinition.from
41
+ #
42
+ # @return [Array<MethodDefinition>]
43
+ def add(*args, type: nil, **options, &block)
44
+ definitions << MethodDefinition.for(type, *args, **options, &block)
27
45
  end
28
46
 
29
47
  private
@@ -36,6 +36,7 @@ class Sinclair
36
36
  # @return (see Sinclair#build)
37
37
  def build
38
38
  add_all_methods
39
+ add_filds_to_equals
39
40
 
40
41
  super
41
42
  end
@@ -60,6 +61,13 @@ class Sinclair
60
61
  klass.allow(option)
61
62
  end
62
63
  end
64
+
65
+ # Add the fields to equals comparation
66
+ #
67
+ # @return (see Sinclair::EqualsChecker#add)
68
+ def add_filds_to_equals
69
+ klass.comparable_by(*attributes.keys)
70
+ end
63
71
  end
64
72
  end
65
73
  end
@@ -24,6 +24,7 @@ class Sinclair
24
24
  autoload :ClassMethods, 'sinclair/options/class_methods'
25
25
 
26
26
  extend ClassMethods
27
+ include Comparable
27
28
 
28
29
  # @param options [Hash] hash with options (see {.options}, {.with_options})
29
30
  # @example (see Options)
@@ -59,19 +60,6 @@ class Sinclair
59
60
  end
60
61
  end
61
62
 
62
- # returns if other equals to self
63
- #
64
- # @param other [Object] object to be compared
65
- #
66
- # @return [TrueClass,FalseClass]
67
- def ==(other)
68
- return false unless self.class == other.class
69
-
70
- allowed_options.all? do |name|
71
- public_send(name) == other.public_send(name)
72
- end
73
- end
74
-
75
63
  private
76
64
 
77
65
  delegate :allowed_options, :skip_validation?, :invalid_options_in, to: :class
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.9.0'
4
+ VERSION = '1.11.0'
5
5
  end
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
- # @example Using string code
195
- # class Person
196
- # attr_reader :first_name, :last_name
197
- #
198
- # def initialize(first_name, last_name)
199
- # @first_name = first_name
200
- # @last_name = last_name
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
- # builder = Sinclair.new(Person)
205
- # builder.add_method(:full_name, '[first_name, last_name].join(" ")')
206
- # builder.build
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
- # Person.new('john', 'wick').full_name # returns 'john wick'
259
+ # person.Person.new('john', 'wick')
209
260
  #
210
- # @example Using block
211
- # class Person
212
- # attr_reader :first_name, :last_name
261
+ # person.bond_name # returns 'wick, john wick'
262
+ # person.first_name = 'Johny'
263
+ # person.bond_name # returns 'wick, john wick'
213
264
  #
214
- # def initialize(first_name, last_name)
215
- # @first_name = first_name
216
- # @last_name = last_name
265
+ # @example Passing type call
266
+ # class Person
217
267
  # end
218
- # end
219
268
  #
220
- # builder = Sinclair.new(Person)
221
- # builder.add_method(:full_name, '[first_name, last_name].join(" ")')
222
- # builder.add_method(:bond_name) { "#{last_name}, #{full_name}" }
223
- # builder.build
269
+ # builder = Sinclair.new(Person)
270
+ # builder.add_method(:attr_accessor, :bond_name, type: :call)
271
+ # builder.build
224
272
  #
225
- # Person.new('john', 'wick').bond_name # returns 'wick, john wick'
226
- # @return [Array<MethodDefinition>]
227
- def add_method(name, code = nil, **options, &block)
228
- definitions.add(
229
- name, code, **options, &block
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
- # @example
247
- # class EnvFetcher
248
- # end
311
+ # @example Adding a method by Block
312
+ # class EnvFetcher
313
+ # end
249
314
  #
250
- # builder = Sinclair.new(EnvFetcher)
315
+ # builder = Sinclair.new(EnvFetcher)
251
316
  #
252
- # builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
253
- # builder.build
317
+ # builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
318
+ # builder.build
254
319
  #
255
- # ENV['HOSTNAME'] = 'myhost'
320
+ # ENV['TIMEOUT'] = '300'
256
321
  #
257
- # env_fetcher.hostname # returns 'myhost'
322
+ # EnvFetcher.timeout # returns '300'
258
323
  #
259
- # @example
260
- # class EnvFetcher
261
- # end
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
- # builder = Sinclair.new(EnvFetcher)
335
+ # @example Passing type block
336
+ # class EnvFetcher
337
+ # end
264
338
  #
265
- # builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
266
- # builder.build
339
+ # builder = Sinclair.new(EnvFetcher)
267
340
  #
268
- # ENV['TIMEOUT'] = '300'
341
+ # builder.add_class_method(:timeout, type: :block) { ENV['TIMEOUT'] }
342
+ # builder.build
269
343
  #
270
- # env_fetcher.timeout # returns '300'
344
+ # ENV['TIMEOUT'] = '300'
271
345
  #
272
- # @return [Array<MethodDefinition>]
273
- def add_class_method(name, code = nil, **options, &block)
274
- class_definitions.add(
275
- name, code, **options, &block
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,47 @@
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 call to the class' do
34
+ it 'performs the call to the class' do
35
+ klass = Class.new
36
+
37
+ builder = described_class.new(klass)
38
+ builder.add_class_method(:attr_accessor, :number, type: :call)
39
+ builder.build
40
+
41
+ expect(klass.number).to be_nil
42
+ klass.number = 10
43
+ expect(klass.number).to eq(10)
44
+ end
45
+ end
46
+ end
47
+ 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