sinclair 1.4.1 → 1.4.2

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 (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,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::InstanceMethodDefinition do
6
+ describe 'yard' do
7
+ describe '#from' do
8
+ describe 'using string method with no options' do
9
+ subject(:method_definition) do
10
+ described_class.from(name, code)
11
+ end
12
+
13
+ let(:klass) { Class.new }
14
+ let(:instance) { klass.new }
15
+ let(:code) { '@x = @x.to_i ** 2 + 1' }
16
+ let(:name) { :sequence }
17
+
18
+ it 'adds a dynamic method' do
19
+ expect { method_definition.build(klass) }.to add_method(name).to(instance)
20
+ expect(instance.sequence).to eq(1)
21
+ expect(instance.sequence).to eq(2)
22
+ expect(instance.sequence).to eq(5)
23
+ end
24
+
25
+ it 'changes instance variable' do
26
+ method_definition.build(klass)
27
+
28
+ expect { instance.sequence }
29
+ .to change { instance.instance_variable_get(:@x) }
30
+ .from(nil).to 1
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- describe Sinclair::MethodDefinition::StringDefinition do
3
+ describe Sinclair::MethodDefinition::InstanceStringDefinition do
4
4
  describe 'yard' do
5
5
  describe '#build' do
6
6
  subject(:method_definition) do
@@ -131,16 +131,43 @@ describe Sinclair do
131
131
  end
132
132
 
133
133
  describe '#full_name' do
134
- let(:klass) { Class.new(Person) }
135
- let(:instance) { klass.new('john', 'wick') }
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 }
136
149
 
150
+ describe '#hostname' do
137
151
  before do
138
- builder.add_method(:full_name, '[first_name, last_name].join(" ")')
152
+ builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
139
153
  builder.build
154
+ ENV['HOSTNAME'] = 'myhost'
140
155
  end
141
156
 
142
- it 'returns the full name' do
143
- expect(instance.bond_name).to eq('wick, john wick')
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')
144
171
  end
145
172
  end
146
173
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::Matchers::AddClassMethod do
6
+ subject(:matcher) { described_class.new(method) }
7
+
8
+ let(:method) { :the_method }
9
+ let(:klass) { Class.new }
10
+
11
+ describe '#to' do
12
+ it do
13
+ expect(matcher.to(klass.new)).to be_a(Sinclair::Matchers::AddClassMethodTo)
14
+ end
15
+
16
+ it 'returns an add_class_method_to' do
17
+ expect(matcher.to(klass)).to eq(Sinclair::Matchers::AddClassMethodTo.new(klass, method))
18
+ end
19
+ end
20
+
21
+ describe '#matches?' do
22
+ it do
23
+ expect { matcher.matches?(proc {}) }
24
+ .to raise_error(
25
+ SyntaxError, 'You should specify which class the method is being added to' \
26
+ "add_class_method(:#{method}).to(klass)"
27
+ )
28
+ end
29
+ end
30
+
31
+ describe '#supports_block_expectations?' do
32
+ it do
33
+ expect(matcher).to be_supports_block_expectations
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::Matchers::AddClassMethodTo do
6
+ subject(:matcher) { described_class.new(klass, method) }
7
+
8
+ let(:method) { :the_method }
9
+ let(:klass) { Class.new }
10
+
11
+ describe '#matches?' do
12
+ let(:event_proc) do
13
+ proc { klass.send(:define_singleton_method, method) {} }
14
+ end
15
+
16
+ context 'when a method is added' do
17
+ it { expect(matcher).to be_matches(event_proc) }
18
+ end
19
+
20
+ context 'when a method is not added' do
21
+ let(:event_proc) { proc {} }
22
+
23
+ it { expect(matcher).not_to be_matches(event_proc) }
24
+ end
25
+
26
+ context 'when the wrong method is added' do
27
+ let(:event_proc) do
28
+ proc { klass.send(:define_singleton_method, :another_method) {} }
29
+ end
30
+
31
+ it { expect(matcher).not_to be_matches(event_proc) }
32
+ end
33
+
34
+ context 'when a block is given' do
35
+ it do
36
+ expect { matcher.matches?(event_proc) { 1 } }
37
+ .to raise_error(
38
+ SyntaxError, 'Block not received by the `add_class_method_to` matcher. ' \
39
+ 'Perhaps you want to use `{ ... }` instead of do/end?'
40
+ )
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#failure_message_for_should' do
46
+ it 'returns information on the instance class and method' do
47
+ expect(matcher.failure_message_for_should)
48
+ .to eq("expected class_method '#{method}' to be added to #{klass} but it didn't")
49
+ end
50
+
51
+ context 'when method already exited' do
52
+ before do
53
+ klass.send(:define_singleton_method, method) {}
54
+ matcher.matches?(proc {})
55
+ end
56
+
57
+ it 'returns information on the instance class and method' do
58
+ expect(matcher.failure_message_for_should)
59
+ .to eq("expected class_method '#{method}' to be added to #{klass} but it already existed")
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '#failure_message_for_should_not' do
65
+ it 'returns information on the instance class and method' do
66
+ expect(matcher.failure_message_for_should_not)
67
+ .to eq("expected class_method '#{method}' not to be added to #{klass} but it was")
68
+ end
69
+ end
70
+
71
+ describe 'description' do
72
+ it 'returns information on the instance class and method' do
73
+ expect(matcher.description)
74
+ .to eq("add method class_method '#{method}' to #{klass}")
75
+ end
76
+ end
77
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Sinclair::Matchers::AddMethod do
5
+ describe Sinclair::Matchers::AddInstanceMethod do
6
6
  subject(:matcher) { described_class.new(method) }
7
7
 
8
8
  let(:method) { :the_method }
@@ -11,11 +11,12 @@ describe Sinclair::Matchers::AddMethod do
11
11
 
12
12
  describe '#to' do
13
13
  it do
14
- expect(matcher.to(klass.new)).to be_a(Sinclair::Matchers::AddMethodTo)
14
+ expect(matcher.to(klass.new)).to be_a(Sinclair::Matchers::AddInstanceMethodTo)
15
15
  end
16
16
 
17
- it 'returns an add_method_to' do
18
- expect(matcher.to(instance)).to eq(Sinclair::Matchers::AddMethodTo.new(instance, method))
17
+ it 'returns an add_instance_method_to' do
18
+ expect(matcher.to(instance))
19
+ .to eq(Sinclair::Matchers::AddInstanceMethodTo.new(instance, method))
19
20
  end
20
21
  end
21
22
 
@@ -28,4 +29,10 @@ describe Sinclair::Matchers::AddMethod do
28
29
  )
29
30
  end
30
31
  end
32
+
33
+ describe '#supports_block_expectations?' do
34
+ it do
35
+ expect(matcher).to be_supports_block_expectations
36
+ end
37
+ end
31
38
  end
@@ -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
  subject(:matcher) { described_class.new(instance, method) }
7
7
 
8
8
  let(:method) { :the_method }
@@ -44,7 +44,7 @@ describe Sinclair::Matchers::AddMethodTo do
44
44
  it do
45
45
  expect { matcher.matches?(event_proc) { 1 } }
46
46
  .to raise_error(
47
- SyntaxError, 'Block not received by the `add_method_to` matcher. ' \
47
+ SyntaxError, 'Block not received by the `add_instance_method_to` matcher. ' \
48
48
  'Perhaps you want to use `{ ... }` instead of do/end?'
49
49
  )
50
50
  end
@@ -9,11 +9,26 @@ describe Sinclair::Matchers do
9
9
  end
10
10
 
11
11
  it do
12
- expect(add_method(:method_name)).to be_a(described_class::AddMethod)
12
+ expect(add_method(:method_name)).to be_a(described_class::AddInstanceMethod)
13
13
  end
14
14
 
15
15
  it 'returns the matcher with correct argument' do
16
- expect(add_method(:method_name)).to eq(described_class::AddMethod.new(:method_name))
16
+ expect(add_method(:method_name)).to eq(described_class::AddInstanceMethod.new(:method_name))
17
+ end
18
+ end
19
+
20
+ describe '#add_class_method' do
21
+ it 'has been added to DSL' do
22
+ expect(respond_to?(:add_class_method)).to be_truthy
23
+ end
24
+
25
+ it do
26
+ expect(add_class_method(:method_name)).to be_a(described_class::AddClassMethod)
27
+ end
28
+
29
+ it 'returns the matcher with correct argument' do
30
+ expect(add_class_method(:method_name))
31
+ .to eq(described_class::AddClassMethod.new(:method_name))
17
32
  end
18
33
  end
19
34
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::ClassBlockDefinition do
6
+ let(:klass) { Class.new }
7
+
8
+ describe '#build' do
9
+ subject(:method_definition) do
10
+ described_class.new(method_name) do
11
+ @x = @x.to_i + 1
12
+ end
13
+ end
14
+
15
+ let(:method_name) { :the_method }
16
+
17
+ it_behaves_like 'ClassMethodDefinition#build without cache'
18
+
19
+ context 'with cached options' do
20
+ subject(:method_definition) do
21
+ described_class.new(method_name, cached: cached_option) do
22
+ @x = @x.to_i + 1
23
+ end
24
+ end
25
+
26
+ it_behaves_like 'ClassMethodDefinition#build with cache options'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::MethodDefinition::ClassStringDefinition do
6
+ let(:klass) { Class.new }
7
+
8
+ describe '#build' do
9
+ subject(:method_definition) do
10
+ described_class.new(method_name, code)
11
+ end
12
+
13
+ let(:method_name) { :the_method }
14
+
15
+ let(:code) { '@x = @x.to_i + 1' }
16
+
17
+ it_behaves_like 'ClassMethodDefinition#build without cache'
18
+
19
+ context 'with cached options' do
20
+ subject(:method_definition) do
21
+ described_class.new(method_name, code, cached: cached_option)
22
+ end
23
+
24
+ it_behaves_like 'ClassMethodDefinition#build with cache options'
25
+ end
26
+ end
27
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Sinclair::MethodDefinition::BlockDefinition do
5
+ describe Sinclair::MethodDefinition::InstanceBlockDefinition do
6
6
  let(:klass) { Class.new }
7
7
  let(:instance) { klass.new }
8
8
 
@@ -19,7 +19,7 @@ describe Sinclair::MethodDefinition::BlockDefinition do
19
19
 
20
20
  context 'with cached options' do
21
21
  subject(:method_definition) do
22
- described_class.from(method_name, cached: cached_option) do
22
+ described_class.new(method_name, cached: cached_option) do
23
23
  @x = @x.to_i + 1
24
24
  end
25
25
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Sinclair::MethodDefinition::StringDefinition do
5
+ describe Sinclair::MethodDefinition::InstanceStringDefinition do
6
6
  let(:klass) { Class.new }
7
7
  let(:instance) { klass.new }
8
8
 
@@ -19,7 +19,7 @@ describe Sinclair::MethodDefinition::StringDefinition do
19
19
 
20
20
  context 'with cached options' do
21
21
  subject(:method_definition) do
22
- described_class.from(method_name, code, cached: cached_option)
22
+ described_class.new(method_name, code, cached: cached_option)
23
23
  end
24
24
 
25
25
  it_behaves_like 'MethodDefinition#build with cache options'
@@ -23,36 +23,40 @@ describe Sinclair::MethodDefinition do
23
23
  end
24
24
  end
25
25
 
26
- context 'when method was defined with a string' do
26
+ context 'when method was defined with a string for instance' do
27
27
  subject(:method_definition) do
28
- described_class.from(method_name, code)
28
+ definition_class.new(method_name, code)
29
29
  end
30
30
 
31
+ let(:definition_class) { described_class::InstanceStringDefinition }
32
+
31
33
  let(:code) { '@x = @x.to_i + 1' }
32
34
 
33
35
  it_behaves_like 'MethodDefinition#build without cache'
34
36
 
35
37
  context 'with cached options' do
36
38
  subject(:method_definition) do
37
- described_class.from(method_name, code, cached: cached_option)
39
+ definition_class.new(method_name, code, cached: cached_option)
38
40
  end
39
41
 
40
42
  it_behaves_like 'MethodDefinition#build with cache options'
41
43
  end
42
44
  end
43
45
 
44
- context 'when method was defined with a block' do
46
+ context 'when method was defined with a block for instance' do
45
47
  subject(:method_definition) do
46
- described_class.from(method_name) do
48
+ definition_class.new(method_name) do
47
49
  @x = @x.to_i + 1
48
50
  end
49
51
  end
50
52
 
53
+ let(:definition_class) { described_class::InstanceBlockDefinition }
54
+
51
55
  it_behaves_like 'MethodDefinition#build without cache'
52
56
 
53
57
  context 'with cached options' do
54
58
  subject(:method_definition) do
55
- described_class.from(method_name, cached: cached_option) do
59
+ definition_class.new(method_name, cached: cached_option) do
56
60
  @x = @x.to_i + 1
57
61
  end
58
62
  end
@@ -60,5 +64,47 @@ describe Sinclair::MethodDefinition do
60
64
  it_behaves_like 'MethodDefinition#build with cache options'
61
65
  end
62
66
  end
67
+
68
+ context 'when method was defined with a string for class' do
69
+ subject(:method_definition) do
70
+ definition_class.new(method_name, code)
71
+ end
72
+
73
+ let(:definition_class) { described_class::ClassStringDefinition }
74
+
75
+ let(:code) { '@x = @x.to_i + 1' }
76
+
77
+ it_behaves_like 'ClassMethodDefinition#build without cache'
78
+
79
+ context 'with cached options' do
80
+ subject(:method_definition) do
81
+ definition_class.new(method_name, code, cached: cached_option)
82
+ end
83
+
84
+ it_behaves_like 'ClassMethodDefinition#build with cache options'
85
+ end
86
+ end
87
+
88
+ context 'when method was defined with a block for class' do
89
+ subject(:method_definition) do
90
+ definition_class.new(method_name) do
91
+ @x = @x.to_i + 1
92
+ end
93
+ end
94
+
95
+ let(:definition_class) { described_class::ClassBlockDefinition }
96
+
97
+ it_behaves_like 'ClassMethodDefinition#build without cache'
98
+
99
+ context 'with cached options' do
100
+ subject(:method_definition) do
101
+ definition_class.new(method_name, cached: cached_option) do
102
+ @x = @x.to_i + 1
103
+ end
104
+ end
105
+
106
+ it_behaves_like 'ClassMethodDefinition#build with cache options'
107
+ end
108
+ end
63
109
  end
64
110
  end