sinclair 1.4.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +5 -3
  3. data/.rubocop.yml +20 -4
  4. data/Dockerfile +8 -4
  5. data/README.md +1 -1
  6. data/config/yardstick.yml +10 -35
  7. data/lib/sinclair.rb +87 -18
  8. data/lib/sinclair/config.rb +3 -0
  9. data/lib/sinclair/config/methods_builder.rb +15 -1
  10. data/lib/sinclair/config_builder.rb +1 -0
  11. data/lib/sinclair/config_class.rb +1 -0
  12. data/lib/sinclair/config_factory.rb +15 -0
  13. data/lib/sinclair/configurable.rb +1 -0
  14. data/lib/sinclair/matchers.rb +20 -6
  15. data/lib/sinclair/matchers/add_class_method.rb +56 -0
  16. data/lib/sinclair/matchers/add_class_method_to.rb +98 -0
  17. data/lib/sinclair/matchers/add_instance_method.rb +85 -0
  18. data/lib/sinclair/matchers/add_instance_method_to.rb +119 -0
  19. data/lib/sinclair/matchers/add_method.rb +11 -73
  20. data/lib/sinclair/matchers/add_method_to.rb +13 -111
  21. data/lib/sinclair/method_definition.rb +18 -58
  22. data/lib/sinclair/method_definition/block_definition.rb +37 -6
  23. data/lib/sinclair/method_definition/class_block_definition.rb +22 -0
  24. data/lib/sinclair/method_definition/class_method_definition.rb +50 -0
  25. data/lib/sinclair/method_definition/class_string_definition.rb +24 -0
  26. data/lib/sinclair/method_definition/instance_block_definition.rb +22 -0
  27. data/lib/sinclair/method_definition/instance_method_definition.rb +48 -0
  28. data/lib/sinclair/method_definition/instance_string_definition.rb +24 -0
  29. data/lib/sinclair/method_definition/string_definition.rb +39 -5
  30. data/lib/sinclair/method_definitions.rb +28 -0
  31. data/lib/sinclair/options_parser.rb +5 -0
  32. data/lib/sinclair/version.rb +1 -1
  33. data/sinclair.gemspec +16 -10
  34. data/spec/integration/yard/sinclair/matchers/add_class_method_spec.rb +23 -0
  35. data/spec/integration/yard/sinclair/matchers/add_class_method_to_spec.rb +19 -0
  36. data/spec/integration/yard/sinclair/matchers/{add_method_spec.rb → add_instance_method_spec.rb} +3 -3
  37. data/spec/integration/yard/sinclair/matchers/{add_method_to_spec.rb → add_instance_method_to_spec.rb} +1 -1
  38. data/spec/integration/yard/sinclair/method_definition/class_block_definition_spec.rb +34 -0
  39. data/spec/integration/yard/sinclair/method_definition/class_method_definition_spec.rb +28 -0
  40. data/spec/integration/yard/sinclair/method_definition/class_string_definition_spec.rb +23 -0
  41. data/spec/integration/yard/sinclair/method_definition/{block_definition_spec.rb → instance_block_definition_spec.rb} +2 -2
  42. data/spec/integration/yard/sinclair/method_definition/instance_method_definition_spec.rb +35 -0
  43. data/spec/integration/yard/sinclair/method_definition/{string_definition_spec.rb → instance_string_definition_spec.rb} +1 -1
  44. data/spec/integration/yard/sinclair_spec.rb +32 -5
  45. data/spec/lib/sinclair/matchers/add_class_method_spec.rb +36 -0
  46. data/spec/lib/sinclair/matchers/add_class_method_to_spec.rb +77 -0
  47. data/spec/lib/sinclair/matchers/{add_method_spec.rb → add_instance_method_spec.rb} +11 -4
  48. data/spec/lib/sinclair/matchers/{add_method_to_spec.rb → add_instance_method_to_spec.rb} +2 -2
  49. data/spec/lib/sinclair/matchers_spec.rb +17 -2
  50. data/spec/lib/sinclair/method_definition/class_block_definition_spec.rb +29 -0
  51. data/spec/lib/sinclair/method_definition/class_string_definition_spec.rb +27 -0
  52. data/spec/lib/sinclair/method_definition/{block_definition_spec.rb → instance_block_definition_spec.rb} +2 -2
  53. data/spec/lib/sinclair/method_definition/{string_definition_spec.rb → instance_string_definition_spec.rb} +2 -2
  54. data/spec/lib/sinclair/method_definition_spec.rb +52 -6
  55. data/spec/lib/sinclair_spec.rb +83 -0
  56. data/spec/support/models/dummy_class_builder.rb +11 -0
  57. data/spec/support/shared_examples/class_method_definition.rb +96 -0
  58. data/spec/support/shared_examples/{method_definition.rb → instance_method_definition.rb} +0 -0
  59. metadata +148 -45
  60. data/scripts/check_readme.sh +0 -6
  61. data/scripts/rubycritic.sh +0 -10
  62. data/spec/integration/sinclair/matchers_spec.rb +0 -99
  63. data/spec/integration/yard/sinclair/method_definition_spec.rb +0 -56
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class MethodDefinition
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Define a method from block
9
+ class InstanceBlockDefinition < BlockDefinition
10
+ private
11
+
12
+ # @private
13
+ #
14
+ # Method used to define an instance method
15
+ #
16
+ # @return [Symbol] Always :define_method
17
+ def method_definer
18
+ :define_method
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class MethodDefinition
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Module responsible for building instance method definitions
9
+ module InstanceMethodDefinition
10
+ # Returns an instance method definition
11
+ #
12
+ # When block is given returns an instance of
13
+ # {InstanceBlockDefinition}, and when not, returns
14
+ # {InstanceStringDefinition}
15
+ #
16
+ # @param name [String,Symbol] name of the method
17
+ # @param code [String] code to be evaluated as method
18
+ # @param block [Proc] block with code to be added as method
19
+ # @param options [Hash] Options of construction
20
+ # @option options cached [Boolean] Flag telling to create
21
+ # a method with cache
22
+ #
23
+ # @example
24
+ # klass = Class.new
25
+ #
26
+ # method_definition = Sinclair::MethodDefinition::InstanceMethodDefinition.from(
27
+ # :sequence, '@x = @x.to_i ** 2 + 1'
28
+ # )
29
+ #
30
+ # method_definition.build(klass)
31
+ #
32
+ # instance = klass.new
33
+ #
34
+ # instance.sequence # returns 1
35
+ # instance.sequence # returns 2
36
+ # instance.sequence # returns 5
37
+ #
38
+ # @return MethodDefinition
39
+ def self.from(name, code = nil, **options, &block)
40
+ if block
41
+ InstanceBlockDefinition.new(name, **options, &block)
42
+ else
43
+ InstanceStringDefinition.new(name, code, **options)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class MethodDefinition
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Define an instance method from string
9
+ class InstanceStringDefinition < StringDefinition
10
+ private
11
+
12
+ # @private
13
+ #
14
+ # String used when defining method
15
+ #
16
+ # Instance definition always returns +name+
17
+ #
18
+ # @return [String]
19
+ def method_name
20
+ name
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,7 +2,12 @@
2
2
 
3
3
  class Sinclair
4
4
  class MethodDefinition
5
- # Define a method from string
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # @abstract
9
+ #
10
+ # Define an instance method from string
6
11
  class StringDefinition < MethodDefinition
7
12
  # @param name [String,Symbol] name of the method
8
13
  # @param code [String] code to be evaluated as method
@@ -22,17 +27,17 @@ class Sinclair
22
27
  #
23
28
  # @return [Symbol] name of the created method
24
29
  #
25
- # @example With no options
30
+ # @example Using instance string method with no options
26
31
  # class MyModel
27
32
  # end
28
33
  #
29
34
  # instance = MyModel.new
30
35
  #
31
- # method_definition = Sinclair::MethodDefinition.from(
36
+ # method_definition = Sinclair::MethodDefinition::InstanceStringDefinition.new(
32
37
  # :sequence, '@x = @x.to_i ** 2 + 1'
33
38
  # )
34
39
  #
35
- # method_definition.build(klass) # adds instance_method :sequence to
40
+ # method_definition.build(MyModel) # adds instance_method :sequence to
36
41
  # # MyModel instances
37
42
  #
38
43
  # instance.instance_variable_get(:@x) # returns nil
@@ -43,12 +48,41 @@ class Sinclair
43
48
  #
44
49
  # instance.instance_variable_get(:@x) # returns 5
45
50
  #
51
+ # @example Using class string method with cache options
52
+ # class MyModel
53
+ # end
54
+ #
55
+ # method_definition = Sinclair::MethodDefinition::ClassStringDefinition.new(
56
+ # :sequence,
57
+ # '@x = @x.to_i ** 2 + 1',
58
+ # cached: true
59
+ # )
60
+ #
61
+ # method_definition.build(MyModel) # adds instance_method :sequence to
62
+ # # MyModel instances
63
+ #
64
+ # MyModel.instance_variable_get(:@sequence) # returns nil
65
+ # MyModel.instance_variable_get(:@x) # returns nil
66
+ #
67
+ # MyModel.sequence # returns 1
68
+ # MyModel.sequence # returns 1 (cached value)
69
+ #
70
+ # MyModel.instance_variable_get(:@sequence) # returns 1
71
+ # MyModel.instance_variable_get(:@x) # returns 1
46
72
  def build(klass)
47
73
  klass.module_eval(code_definition, __FILE__, __LINE__ + 1)
48
74
  end
49
75
 
50
76
  private
51
77
 
78
+ # @method code
79
+ # @private
80
+ #
81
+ # Code to be evaluated as method
82
+ #
83
+ # @return [String]
84
+ attr_reader :code
85
+
52
86
  # @private
53
87
  #
54
88
  # Builds full code of method
@@ -58,7 +92,7 @@ class Sinclair
58
92
  code_line = cached? ? code_with_cache : code
59
93
 
60
94
  <<-CODE
61
- def #{name}
95
+ def #{method_name}
62
96
  #{code_line}
63
97
  end
64
98
  CODE
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ # @api private
5
+ # @author darthjee
6
+ #
7
+ # Enumerator holding all method definitions
8
+ class MethodDefinitions < Array
9
+ # Builds and adds new definition
10
+ #
11
+ # @param definition_class [Class] class used to define method definition
12
+ # @param name [String,Symbol] method name
13
+ # @param options [Hash] Options of construction
14
+ # @option options cached [Boolean] Flag telling to create
15
+ # a method with cache
16
+ #
17
+ # @overload add(definition_class, name, code = nil, **options)
18
+ # @param code [String] code to be evaluated when the method is ran
19
+ #
20
+ # @overload add(definition_class, name, **options, &block)
21
+ # @param block [Proc] block to be ran as method
22
+ #
23
+ # @return MethodDefinitions
24
+ def add(definition_class, name, code = nil, **options, &block)
25
+ self << definition_class.from(name, code, **options, &block)
26
+ end
27
+ end
28
+ end
@@ -33,9 +33,14 @@ class Sinclair
33
33
  private
34
34
 
35
35
  # @!visibility public
36
+ #
37
+ # Options hash
38
+ #
39
+ # @return [Hash]
36
40
  attr_reader :options
37
41
 
38
42
  # @!visibility public
43
+ # @api public
39
44
  #
40
45
  # Builds an openstruct of the Hash
41
46
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.4.1'
4
+ VERSION = '1.4.2'
5
5
  end
@@ -21,14 +21,20 @@ Gem::Specification.new do |gem|
21
21
 
22
22
  gem.add_runtime_dependency 'activesupport', '~> 5.2.0'
23
23
 
24
- gem.add_development_dependency 'bundler', '~> 1.16.1'
25
- gem.add_development_dependency 'pry-nav', '~> 0.2.4'
26
- gem.add_development_dependency 'rake', '>= 12.3.1'
27
- gem.add_development_dependency 'rspec', '>= 3.8'
28
- gem.add_development_dependency 'rubocop', '0.58.1'
29
- gem.add_development_dependency 'rubocop-rspec', '1.30.0'
30
- gem.add_development_dependency 'rubycritic', '>= 4.0.2'
31
- gem.add_development_dependency 'simplecov', '~> 0.16.x'
32
- gem.add_development_dependency 'yard', '>= 0.9.18'
33
- gem.add_development_dependency 'yardstick', '>= 0.9.9'
24
+ gem.add_development_dependency 'bundler', '~> 1.16.1'
25
+ gem.add_development_dependency 'pry', '0.12.2'
26
+ gem.add_development_dependency 'pry-nav', '0.3.0'
27
+ gem.add_development_dependency 'rake', '12.3.3'
28
+ gem.add_development_dependency 'reek', '5.4.0'
29
+ gem.add_development_dependency 'rspec', '3.8.0'
30
+ gem.add_development_dependency 'rspec-core', '3.8.0'
31
+ gem.add_development_dependency 'rspec-expectations', '3.8.3'
32
+ gem.add_development_dependency 'rspec-mocks', '3.8.0'
33
+ gem.add_development_dependency 'rspec-support', '3.8.0'
34
+ gem.add_development_dependency 'rubocop', '0.73.0'
35
+ gem.add_development_dependency 'rubocop-rspec', '1.33.0'
36
+ gem.add_development_dependency 'rubycritic', '4.1.0'
37
+ gem.add_development_dependency 'simplecov', '0.17.0'
38
+ gem.add_development_dependency 'yard', '0.9.19'
39
+ gem.add_development_dependency 'yardstick', '0.9.9'
34
40
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Sinclair::Matchers::AddClassMethod do
6
+ describe 'yard' do
7
+ describe '#to' do
8
+ context 'when checking against Class' do
9
+ let(:clazz) { Class.new(MyModel) }
10
+
11
+ let(:block) do
12
+ proc do
13
+ clazz.define_singleton_method(:new_method) { 2 }
14
+ end
15
+ end
16
+
17
+ it do
18
+ expect(&block).to add_class_method(:new_method).to(clazz)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::Matchers::AddClassMethodTo do
6
+ describe 'yard' do
7
+ let(:klass) { Class.new(MyModel) }
8
+
9
+ let(:block) do
10
+ proc do
11
+ klass.define_singleton_method(:parent_name) { superclass.name }
12
+ end
13
+ end
14
+
15
+ it do
16
+ expect(&block).to add_class_method(:parent_name).to(klass)
17
+ end
18
+ end
19
+ end
@@ -2,11 +2,11 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Sinclair::Matchers::AddMethod do
5
+ RSpec.describe Sinclair::Matchers::AddInstanceMethod do
6
6
  describe 'yard' do
7
7
  describe '#to' do
8
8
  context 'when checking against Class' do
9
- let(:clazz) { Class.new }
9
+ let(:clazz) { Class.new(MyModel) }
10
10
  let(:builder) { Sinclair.new(clazz) }
11
11
 
12
12
  before do
@@ -19,7 +19,7 @@ RSpec.describe Sinclair::Matchers::AddMethod do
19
19
  end
20
20
 
21
21
  context 'when checking against instance' do
22
- let(:clazz) { Class.new }
22
+ let(:clazz) { Class.new(MyModel) }
23
23
  let(:builder) { Sinclair.new(clazz) }
24
24
  let(:instance) { clazz.new }
25
25
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Sinclair::Matchers::AddMethodTo do
5
+ describe Sinclair::Matchers::AddInstanceMethodTo do
6
6
  describe 'yard' do
7
7
  let(:klass) { Class.new(MyModel) }
8
8
  let(:builder) { Sinclair.new(klass) }
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::ClassBlockDefinition do
6
+ describe 'yard' do
7
+ describe '#build' do
8
+ subject(:method_definition) do
9
+ described_class.new(name) do
10
+ @x = @x.to_i**2 + 1
11
+ end
12
+ end
13
+
14
+ let(:klass) { Class.new }
15
+ let(:name) { :sequence }
16
+
17
+ it 'adds a dynamic method' do
18
+ expect { method_definition.build(klass) }.to add_class_method(name).to(klass)
19
+ expect { klass.sequence }
20
+ .to change { klass.instance_variable_get(:@x) }.from(nil).to 1
21
+ expect(klass.sequence).to eq(2)
22
+ expect(klass.sequence).to eq(5)
23
+ end
24
+
25
+ it 'changes instance variable' do
26
+ method_definition.build(klass)
27
+
28
+ expect { klass.sequence }
29
+ .to change { klass.instance_variable_get(:@x) }
30
+ .from(nil).to 1
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::ClassMethodDefinition do
6
+ describe 'yard' do
7
+ describe '#build' do
8
+ describe 'using block with cache option' do
9
+ subject(:method_definition) do
10
+ described_class.from(name, cached: true) do
11
+ @x = @x.to_i**2 + 1
12
+ end
13
+ end
14
+
15
+ let(:klass) { Class.new }
16
+ let(:name) { :sequence }
17
+
18
+ it 'adds a dynamic method' do
19
+ expect { method_definition.build(klass) }.to add_class_method(name).to(klass)
20
+ expect { klass.sequence }
21
+ .to change { klass.instance_variable_get(:@x) }.from(nil).to 1
22
+ expect { klass.sequence }.not_to change(klass, :sequence)
23
+ expect(klass.instance_variable_get(:@sequence)).to eq(1)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Sinclair::MethodDefinition::ClassStringDefinition do
4
+ describe 'yard' do
5
+ describe '#build' do
6
+ subject(:method_definition) do
7
+ described_class.new(name, code, cached: true)
8
+ end
9
+
10
+ let(:klass) { Class.new }
11
+ let(:code) { '@x = @x.to_i ** 2 + 1' }
12
+ let(:name) { :sequence }
13
+
14
+ it 'adds a dynamic method' do
15
+ expect { method_definition.build(klass) }.to add_class_method(name).to(klass)
16
+ expect { klass.sequence }
17
+ .to change { klass.instance_variable_get(:@x) }.from(nil).to(1)
18
+ expect { klass.sequence }.not_to change(klass, :sequence)
19
+ expect(klass.instance_variable_get(:@sequence)).to eq(1)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- describe Sinclair::MethodDefinition::BlockDefinition do
3
+ describe Sinclair::MethodDefinition::InstanceBlockDefinition do
4
4
  describe 'yard' do
5
5
  describe '#build' do
6
6
  subject(:method_definition) do
7
- described_class.from(name, cached: true) do
7
+ described_class.new(name, cached: true) do
8
8
  @x = @x.to_i**2 + 1
9
9
  end
10
10
  end