compo 0.1.5 → 0.2.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.
data/spec/movable_spec.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'compo'
3
+ require 'movable_shared_examples'
3
4
 
4
5
  # Mock implementation of a Movable
5
6
  class MockMovable
@@ -7,195 +8,5 @@ class MockMovable
7
8
  end
8
9
 
9
10
  describe MockMovable do
10
- let(:old_parent) { double(:old_parent) }
11
- let(:new_parent) { double(:new_parent) }
12
-
13
- describe '#move_to' do
14
- context 'when the receiving parent is nil' do
15
- context 'and the Movable has no parent' do
16
- before(:each) do
17
- allow(subject).to receive(:parent).and_return(nil)
18
- end
19
-
20
- it 'returns itself' do
21
- expect(subject.move_to(nil, :test)).to eq(subject)
22
- end
23
-
24
- it 'calls #parent' do
25
- expect(subject).to receive(:parent).once
26
- subject.move_to(nil, :test)
27
- end
28
- end
29
-
30
- context 'and the Movable has a parent' do
31
- before(:each) do
32
- allow(subject).to receive(:parent).and_return(old_parent)
33
- allow(old_parent).to receive(:remove)
34
- end
35
-
36
- it 'returns itself' do
37
- expect(subject.move_to(nil, :test)).to eq(subject)
38
- end
39
-
40
- it 'calls #parent' do
41
- expect(subject).to receive(:parent)
42
- subject.move_to(nil, :test)
43
- end
44
-
45
- it 'calls #remove on the old parent with the Movable' do
46
- expect(old_parent).to receive(:remove).once.with(subject)
47
- subject.move_to(nil, :test)
48
- end
49
- end
50
- end
51
-
52
- context 'when the receiving parent refuses to add the Movable' do
53
- before(:each) do
54
- allow(new_parent).to receive(:add).and_return(nil)
55
- end
56
-
57
- context 'and the Movable has no parent' do
58
- before(:each) do
59
- allow(subject).to receive(:parent).and_return(nil)
60
- end
61
-
62
- it 'returns itself' do
63
- expect(subject.move_to(new_parent, :test)).to eq(subject)
64
- end
65
-
66
- it 'calls #parent' do
67
- expect(subject).to receive(:parent)
68
- subject.move_to(new_parent, :test)
69
- end
70
-
71
- it 'calls #add on the new parent with the ID and Movable' do
72
- expect(new_parent).to receive(:add).once.with(:test, subject)
73
- subject.move_to(new_parent, :test)
74
- end
75
- end
76
-
77
- context 'and the Movable has a parent that refuses to remove it' do
78
- before(:each) do
79
- allow(subject).to receive(:parent).and_return(old_parent)
80
- allow(old_parent).to receive(:remove).and_return(nil)
81
- end
82
-
83
- it 'returns itself' do
84
- expect(subject.move_to(new_parent, :test)).to eq(subject)
85
- end
86
-
87
- it 'calls #parent' do
88
- expect(subject).to receive(:parent)
89
- subject.move_to(new_parent, :test)
90
- end
91
-
92
- it 'calls #remove on the old parent with the Movable' do
93
- expect(old_parent).to receive(:remove).once.with(subject)
94
- subject.move_to(new_parent, :test)
95
- end
96
- end
97
-
98
- context 'and the Movable has a parent that allows it to be removed' do
99
- before(:each) do
100
- allow(subject).to receive(:parent).and_return(old_parent)
101
- allow(old_parent).to receive(:remove).and_return(subject)
102
- allow(new_parent).to receive(:add)
103
- end
104
-
105
- it 'returns itself' do
106
- expect(subject.move_to(new_parent, :test)).to eq(subject)
107
- end
108
-
109
- it 'calls #parent' do
110
- expect(subject).to receive(:parent)
111
- subject.move_to(new_parent, :test)
112
- end
113
-
114
- it 'calls #remove on the old parent with the Movable' do
115
- expect(old_parent).to receive(:remove).once.with(subject)
116
- subject.move_to(new_parent, :test)
117
- end
118
-
119
- it 'calls #add on the new parent with the ID and Movable' do
120
- expect(new_parent).to receive(:add).once.with(:test, subject)
121
- subject.move_to(new_parent, :test)
122
- end
123
- end
124
- end
125
-
126
- context 'when the receiving parent allows the Movable to be added' do
127
- before(:each) do
128
- allow(new_parent).to receive(:add).and_return(subject)
129
- end
130
-
131
- context 'and the Movable has no parent' do
132
- before(:each) do
133
- allow(subject).to receive(:parent).and_return(nil)
134
- end
135
-
136
- it 'returns itself' do
137
- expect(subject.move_to(new_parent, :test)).to eq(subject)
138
- end
139
-
140
- it 'calls #parent' do
141
- expect(subject).to receive(:parent)
142
- subject.move_to(new_parent, :test)
143
- end
144
-
145
- it 'calls #add on the new parent with the ID and Movable' do
146
- expect(new_parent).to receive(:add).with(:test_id, subject)
147
-
148
- subject.move_to(new_parent, :test_id)
149
- end
150
- end
151
-
152
- context 'and the Movable has a parent that refuses to remove it' do
153
- before(:each) do
154
- allow(subject).to receive(:parent).and_return(old_parent)
155
- allow(old_parent).to receive(:remove).and_return(nil)
156
- end
157
-
158
- it 'returns itself' do
159
- expect(subject.move_to(new_parent, :test)).to eq(subject)
160
- end
161
-
162
- it 'calls #parent' do
163
- expect(subject).to receive(:parent)
164
- subject.move_to(new_parent, :test)
165
- end
166
-
167
- it 'calls #remove on the old parent with the Movable' do
168
- expect(old_parent).to receive(:remove).once.with(subject)
169
- subject.move_to(new_parent, :test)
170
- end
171
- end
172
-
173
- context 'and the Movable has a parent that allows it to be removed' do
174
- before(:each) do
175
- allow(subject).to receive(:parent).and_return(old_parent)
176
- allow(old_parent).to receive(:remove).and_return(subject)
177
- allow(new_parent).to receive(:add)
178
- end
179
-
180
- it 'returns itself' do
181
- expect(subject.move_to(new_parent, :test)).to eq(subject)
182
- end
183
-
184
- it 'calls #parent' do
185
- expect(subject).to receive(:parent)
186
- subject.move_to(new_parent, :test)
187
- end
188
-
189
- it 'calls #remove on the old parent with the Movable' do
190
- expect(old_parent).to receive(:remove).once.with(subject)
191
- subject.move_to(new_parent, :test)
192
- end
193
-
194
- it 'calls #add on the new parent with the ID and Movable' do
195
- expect(new_parent).to receive(:add).once.with(:test, subject)
196
- subject.move_to(new_parent, :test)
197
- end
198
- end
199
- end
200
- end
11
+ it_behaves_like 'a movable object'
201
12
  end
@@ -0,0 +1,68 @@
1
+ require 'composite_shared_examples'
2
+
3
+ shared_examples 'a null composite' do
4
+ it_behaves_like 'a composite'
5
+
6
+ let(:child1) { double(:child1) }
7
+ let(:child2) { double(:child2) }
8
+ let(:child3) { double(:child3) }
9
+
10
+ describe '#add' do
11
+ it 'always returns nil' do
12
+ expect(subject.add(1, child1)).to be_nil
13
+ expect(subject.add(:a, child2)).to be_nil
14
+ expect(subject.add(nil, child3)).to be_nil
15
+ end
16
+
17
+ it 'does not change the result of #children' do
18
+ expect(subject.children).to eq({})
19
+
20
+ subject.add(1, child1)
21
+ expect(subject.children).to eq({})
22
+
23
+ subject.add(:a, child2)
24
+ expect(subject.children).to eq({})
25
+
26
+ subject.add(:a, child3)
27
+ expect(subject.children).to eq({})
28
+ end
29
+ end
30
+
31
+ describe '#remove' do
32
+ specify { expect(subject.remove(child1)).to eq(nil) }
33
+
34
+ it 'does not change the result of #children' do
35
+ expect(subject.children).to eq({})
36
+
37
+ subject.remove(child1)
38
+ expect(subject.children).to eq({})
39
+
40
+ subject.remove(child2)
41
+ expect(subject.children).to eq({})
42
+
43
+ subject.remove(child3)
44
+ expect(subject.children).to eq({})
45
+ end
46
+ end
47
+
48
+ describe '#remove_id' do
49
+ specify { expect(subject.remove_id(:a)).to eq(nil) }
50
+
51
+ it 'does not change the result of #children' do
52
+ expect(subject.children).to eq({})
53
+
54
+ subject.remove_id(0)
55
+ expect(subject.children).to eq({})
56
+
57
+ subject.remove_id(:a)
58
+ expect(subject.children).to eq({})
59
+
60
+ subject.remove_id(nil)
61
+ expect(subject.children).to eq({})
62
+ end
63
+ end
64
+
65
+ describe '#children' do
66
+ specify { expect(subject.children).to eq({}) }
67
+ end
68
+ end
@@ -1,67 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'compo'
3
+ require 'null_composite_shared_examples'
3
4
 
4
5
  describe Compo::NullComposite do
5
- let(:child1) { double(:child1) }
6
- let(:child2) { double(:child2) }
7
- let(:child3) { double(:child3) }
8
-
9
- describe '#add' do
10
- it 'always returns nil' do
11
- expect(subject.add(1, child1)).to be_nil
12
- expect(subject.add(:a, child2)).to be_nil
13
- expect(subject.add(nil, child3)).to be_nil
14
- end
15
-
16
- it 'does not change the result of #children' do
17
- expect(subject.children).to eq({})
18
-
19
- subject.add(1, child1)
20
- expect(subject.children).to eq({})
21
-
22
- subject.add(:a, child2)
23
- expect(subject.children).to eq({})
24
-
25
- subject.add(:a, child3)
26
- expect(subject.children).to eq({})
27
- end
28
- end
29
-
30
- describe '#remove' do
31
- specify { expect(subject.remove(child1)).to eq(nil) }
32
-
33
- it 'does not change the result of #children' do
34
- expect(subject.children).to eq({})
35
-
36
- subject.remove(child1)
37
- expect(subject.children).to eq({})
38
-
39
- subject.remove(child2)
40
- expect(subject.children).to eq({})
41
-
42
- subject.remove(child3)
43
- expect(subject.children).to eq({})
44
- end
45
- end
46
-
47
- describe '#remove_id' do
48
- specify { expect(subject.remove_id(:a)).to eq(nil) }
49
-
50
- it 'does not change the result of #children' do
51
- expect(subject.children).to eq({})
52
-
53
- subject.remove_id(0)
54
- expect(subject.children).to eq({})
55
-
56
- subject.remove_id(:a)
57
- expect(subject.children).to eq({})
58
-
59
- subject.remove_id(nil)
60
- expect(subject.children).to eq({})
61
- end
62
- end
63
-
64
- describe '#children' do
65
- specify { expect(subject.children).to eq({}) }
66
- end
6
+ it_behaves_like 'a null composite'
67
7
  end
@@ -50,9 +50,9 @@ describe MockParentTracker do
50
50
  end
51
51
 
52
52
  describe '#remove_parent' do
53
- it 'sets the parent to nil' do
53
+ it 'sets the parent to an instance of Parentless' do
54
54
  subject.remove_parent
55
- expect(subject.parent).to be_nil
55
+ expect(subject.parent).to be_a(Compo::Parentless)
56
56
  end
57
57
 
58
58
  it 'sets the ID function to one returning nil' do
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'compo'
3
+
4
+ describe Compo::Parentless do
5
+ let(:child) { double(:child) }
6
+
7
+ describe '#add' do
8
+ before(:each) { allow(child).to receive(:update_parent) }
9
+
10
+ it 'returns the given child exactly' do
11
+ expect(subject.add(:id, child)).to be(child)
12
+ end
13
+
14
+ it 'calls #update_parent on the child with a Parentless' do
15
+ expect(child).to receive(:update_parent).once do |parent, _|
16
+ expect(parent).to be_a(Compo::Parentless)
17
+ end
18
+ subject.add(:id, child)
19
+ end
20
+
21
+ it 'calls #update_parent on the child with a nil-returning ID proc' do
22
+ expect(child).to receive(:update_parent).once do |_, idp|
23
+ expect(idp.call).to be_nil
24
+ end
25
+ subject.add(:id, child)
26
+ end
27
+ end
28
+
29
+ describe '#remove' do
30
+ it 'returns the given child exactly' do
31
+ expect(subject.remove(child)).to be(child)
32
+ end
33
+ end
34
+
35
+ describe '#children' do
36
+ specify { expect(subject.children).to eq({}) }
37
+ end
38
+
39
+ describe '#url' do
40
+ specify { expect(subject.url).to eq('') }
41
+ end
42
+
43
+ describe '#child_url' do
44
+ specify { expect(subject.child_url(:id)).to eq('') }
45
+ end
46
+
47
+ describe '#parent' do
48
+ it 'returns the exact same Parentless object' do
49
+ expect(subject.parent).to be(subject)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,78 @@
1
+ shared_examples 'a URL referenceable object' do
2
+ let(:parent) { nil }
3
+ let(:id) { double(:id) }
4
+
5
+ before(:each) do
6
+ allow(subject).to receive(:id).and_return(id)
7
+ allow(subject).to receive(:parent).and_return(parent)
8
+ end
9
+
10
+ describe '#url' do
11
+ context 'when the UrlReferenceable has no parent' do
12
+ specify { expect { subject.url }.to raise_error }
13
+ end
14
+
15
+ context 'when the UrlReferenceable has a parent' do
16
+ let(:parent) { double(:parent) }
17
+ before(:each) do
18
+ allow(parent).to receive(:child_url).and_return(:child_url)
19
+ end
20
+
21
+ it 'calls #id' do
22
+ expect(subject).to receive(:id)
23
+ subject.url
24
+ end
25
+
26
+ it 'calls #parent' do
27
+ expect(subject).to receive(:parent)
28
+ subject.url
29
+ end
30
+
31
+ it 'calls #child_url on the parent with the ID' do
32
+ expect(parent).to receive(:child_url).with(id)
33
+ subject.url
34
+ end
35
+
36
+ it 'returns the result of calling #child_url' do
37
+ expect(subject.url).to eq(:child_url)
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '#parent_url' do
43
+ context 'when the UrlReferenceable has no parent' do
44
+ let(:parent) { nil }
45
+
46
+ specify { expect(subject.parent_url).to be_nil }
47
+
48
+ it 'calls #parent' do
49
+ expect(subject).to receive(:parent)
50
+ subject.parent_url
51
+ end
52
+ end
53
+
54
+ context 'when the UrlReferenceable has a parent' do
55
+ let(:parent) { double(:parent) }
56
+ let(:url) { double(:url) }
57
+
58
+ before(:each) do
59
+ allow(parent).to receive(:url).and_return(url)
60
+ end
61
+
62
+ it 'calls #parent' do
63
+ expect(subject).to receive(:parent).with(no_args)
64
+ subject.parent_url
65
+ end
66
+
67
+ it 'calls #url on the parent' do
68
+ expect(parent).to receive(:url).once.with(no_args)
69
+ subject.parent_url
70
+ end
71
+
72
+ it 'returns the result of #url on the parent' do
73
+ expect(subject.parent_url).to eq(url)
74
+ subject.parent_url
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'compo'
3
+ require 'url_referenceable_shared_examples'
3
4
 
4
5
  # Mock implementation of UrlReferenceable.
5
6
  class MockUrlReferenceable
@@ -7,69 +8,5 @@ class MockUrlReferenceable
7
8
  end
8
9
 
9
10
  describe MockUrlReferenceable do
10
- before(:each) { allow(subject).to receive(:parent).and_return(parent) }
11
-
12
- describe '#url' do
13
- context 'when the UrlReferenceable has no parent' do
14
- let(:parent) { nil }
15
-
16
- it 'returns the empty string' do
17
- expect(subject.url).to eq('')
18
- end
19
- end
20
-
21
- context 'when the UrlReferenceable has a parent' do
22
- let(:parent) { double(:parent) }
23
- before(:each) do
24
- allow(subject).to receive(:id).and_return('id')
25
- allow(subject).to receive(:parent_url).and_return('dog/goes')
26
- end
27
-
28
- it 'calls #id' do
29
- expect(subject).to receive(:id)
30
- subject.url
31
- end
32
-
33
- it 'returns the joining of the parent URL and ID with a slash' do
34
- expect(subject.url).to eq('dog/goes/id')
35
- end
36
- end
37
- end
38
-
39
- describe '#parent_url' do
40
- context 'when the UrlReferenceable has no parent' do
41
- let(:parent) { nil }
42
-
43
- specify { expect(subject.parent_url).to be_nil }
44
-
45
- it 'calls #parent' do
46
- expect(subject).to receive(:parent)
47
- subject.parent_url
48
- end
49
- end
50
-
51
- context 'when the UrlReferenceable has a parent' do
52
- let(:parent) { double(:parent) }
53
- let(:url) { double(:url) }
54
-
55
- before(:each) do
56
- allow(parent).to receive(:url).and_return(url)
57
- end
58
-
59
- it 'calls #parent' do
60
- expect(subject).to receive(:parent).with(no_args)
61
- subject.parent_url
62
- end
63
-
64
- it 'calls #url on the parent' do
65
- expect(parent).to receive(:url).once.with(no_args)
66
- subject.parent_url
67
- end
68
-
69
- it 'returns the result of #url on the parent' do
70
- expect(subject.parent_url).to eq(url)
71
- subject.parent_url
72
- end
73
- end
74
- end
11
+ it_behaves_like 'a URL referenceable object'
75
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Windsor
@@ -149,18 +149,27 @@ files:
149
149
  - lib/compo/movable.rb
150
150
  - lib/compo/null_composite.rb
151
151
  - lib/compo/parent_tracker.rb
152
+ - lib/compo/parentless.rb
152
153
  - lib/compo/url_referenceable.rb
153
154
  - lib/compo/version.rb
154
155
  - spec/array_branch_spec.rb
156
+ - spec/array_composite_shared_examples.rb
155
157
  - spec/array_composite_spec.rb
158
+ - spec/branch_shared_examples.rb
159
+ - spec/composite_shared_examples.rb
156
160
  - spec/composite_spec.rb
157
161
  - spec/hash_branch_spec.rb
162
+ - spec/hash_composite_shared_examples.rb
158
163
  - spec/hash_composite_spec.rb
159
164
  - spec/leaf_spec.rb
165
+ - spec/movable_shared_examples.rb
160
166
  - spec/movable_spec.rb
167
+ - spec/null_composite_shared_examples.rb
161
168
  - spec/null_composite_spec.rb
162
169
  - spec/parent_tracker_spec.rb
170
+ - spec/parentless_spec.rb
163
171
  - spec/spec_helper.rb
172
+ - spec/url_referenceable_shared_examples.rb
164
173
  - spec/url_referenceable_spec.rb
165
174
  homepage: http://github.com/CaptainHayashi/compo
166
175
  licenses:
@@ -188,14 +197,22 @@ specification_version: 4
188
197
  summary: Composite pattern style mixins with IDs
189
198
  test_files:
190
199
  - spec/array_branch_spec.rb
200
+ - spec/array_composite_shared_examples.rb
191
201
  - spec/array_composite_spec.rb
202
+ - spec/branch_shared_examples.rb
203
+ - spec/composite_shared_examples.rb
192
204
  - spec/composite_spec.rb
193
205
  - spec/hash_branch_spec.rb
206
+ - spec/hash_composite_shared_examples.rb
194
207
  - spec/hash_composite_spec.rb
195
208
  - spec/leaf_spec.rb
209
+ - spec/movable_shared_examples.rb
196
210
  - spec/movable_spec.rb
211
+ - spec/null_composite_shared_examples.rb
197
212
  - spec/null_composite_spec.rb
198
213
  - spec/parent_tracker_spec.rb
214
+ - spec/parentless_spec.rb
199
215
  - spec/spec_helper.rb
216
+ - spec/url_referenceable_shared_examples.rb
200
217
  - spec/url_referenceable_spec.rb
201
218
  has_rdoc: