police-dataflow 0.0.1 → 0.0.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.
@@ -4,44 +4,44 @@ describe Police::DataFlow do
4
4
  before do
5
5
  @object = 'Hello'
6
6
  @class = @object.class
7
- @label = AutoFlowFixture.new
7
+ @label = StickyFixture.new
8
8
  end
9
-
9
+
10
10
  describe '#label' do
11
11
  describe 'with a single label' do
12
12
  before do
13
13
  @object = Police::DataFlow.label @object, @label
14
14
  end
15
-
15
+
16
16
  it 'labels the object correctly' do
17
17
  Police::DataFlow.labels(@object).must_equal [@label]
18
18
  end
19
-
19
+
20
20
  it 'is idempotent' do
21
21
  same_object = Police::DataFlow.label @object, @label
22
22
  same_object.must_equal @object
23
23
  Police::DataFlow.labels(@object).must_equal [@label]
24
24
  end
25
-
25
+
26
26
  it 'returns a working proxy' do
27
27
  @object.length.must_equal 5
28
28
  @object.class.must_equal @class
29
29
  end
30
-
30
+
31
31
  it 'returns a label-preserving proxy' do
32
32
  @object << ' world'
33
33
  @object.length.must_equal 11
34
34
  Police::DataFlow.labels(@object).must_equal [@label]
35
35
  end
36
36
  end
37
-
37
+
38
38
  describe 'with two labels' do
39
39
  before do
40
40
  @label2 = NoFlowFixture.new
41
41
  @object = Police::DataFlow.label @object, @label
42
42
  @object = Police::DataFlow.label @object, @label2
43
43
  end
44
-
44
+
45
45
  it 'labels the object correctly' do
46
46
  Set.new(Police::DataFlow.labels(@object)).
47
47
  must_equal Set.new([@label, @label2])
@@ -4,64 +4,89 @@ describe Police::DataFlow do
4
4
  before do
5
5
  @object = 'Hello'
6
6
  @class = @object.class
7
- @p_label = AutoFlowFixture.new
7
+ @p_label = StickyFixture.new
8
8
  end
9
-
10
- describe '#label' do
9
+
10
+ describe '.label' do
11
11
  describe 'with a single label' do
12
12
  before do
13
13
  @object = Police::DataFlow.label @object, @p_label
14
14
  end
15
-
15
+
16
16
  it 'labels the object correctly' do
17
17
  Police::DataFlow.labels(@object).must_equal [@p_label]
18
18
  end
19
-
19
+
20
20
  it 'is idempotent' do
21
21
  same_object = Police::DataFlow.label @object, @p_label
22
22
  same_object.must_equal @object
23
+ same_object.__id__.must_equal @object.__id__
23
24
  Police::DataFlow.labels(@object).must_equal [@p_label]
24
25
  end
25
-
26
+
26
27
  it 'is idempotent vs label type' do
27
-
28
+ p_label2 = StickyFixture.new
29
+ same_object = Police::DataFlow.label @object, p_label2
30
+ same_object.must_equal @object
31
+ same_object.__id__.must_equal @object.__id__
32
+ Police::DataFlow.labels(@object).sort_by(&:__id__).must_equal(
33
+ [@p_label, p_label2].sort_by(&:__id__))
28
34
  end
29
-
35
+
30
36
  it 'returns a working proxy' do
31
37
  @object.length.must_equal 5
32
38
  @object.class.must_equal @class
33
39
  end
34
-
40
+
35
41
  it 'returns a label-preserving proxy' do
36
42
  @object << ' world'
37
43
  @object.length.must_equal 11
38
44
  Police::DataFlow.labels(@object).must_equal [@p_label]
39
45
  end
40
-
46
+
41
47
  it 'returns a label-propagating proxy' do
42
48
  Police::DataFlow.labels(@object[2..5]).must_equal [@p_label]
43
49
  end
44
50
  end
45
-
51
+
46
52
  describe 'with two labels' do
47
53
  before do
48
54
  @n_label = NoFlowFixture.new
49
55
  @object = Police::DataFlow.label @object, @p_label
50
56
  @object = Police::DataFlow.label @object, @n_label
51
57
  end
52
-
58
+
53
59
  it 'labels the object correctly' do
54
60
  Set.new(Police::DataFlow.labels(@object)).
55
61
  must_equal Set.new([@p_label, @n_label])
56
62
  end
57
-
63
+
58
64
  it 'propagates the labels correctly' do
59
65
  Police::DataFlow.labels(@object[2..5]).must_equal [@p_label]
60
66
  end
61
67
  end
68
+
69
+ describe 'on built-in Fixnums' do
70
+ before do
71
+ @number = Police::DataFlow.label 21, @p_label
72
+ end
73
+
74
+ it 'returns a working proxy' do
75
+ (@number * 2).must_equal 42
76
+ (2 * @number).must_equal 42
77
+ end
78
+
79
+ it 'returns a label-propagating proxy' do
80
+ Police::DataFlow.labels(@number * 2).must_equal [@p_label]
81
+ end
82
+
83
+ it 'returns a proxy that coerces numbers correctly' do
84
+ Police::DataFlow.labels(2 * @number).must_equal [@p_label]
85
+ end
86
+ end
62
87
  end
63
-
64
- describe '#labels' do
88
+
89
+ describe '.labels' do
65
90
  it 'returns an empty array for un-labeled objects' do
66
91
  Police::DataFlow.labels(@object).must_equal []
67
92
  end
@@ -71,4 +96,288 @@ describe Police::DataFlow do
71
96
  Police::DataFlow.labels(labeled).must_equal [@p_label]
72
97
  end
73
98
  end
99
+
100
+ end
101
+
102
+ describe Police::DataFlow::Labeling do
103
+ before do
104
+ @n1_label = NoFlowFixture.new
105
+ @n2_label = NoFlowFixture.new
106
+ @s1_label = StickyFixture.new
107
+ @s2_label = StickyFixture.new
108
+ @h1_label = HooksFlowFixture.new
109
+ end
110
+
111
+ describe '.add_label_to_set' do
112
+ before do
113
+ @set = {
114
+ NoFlowFixture.__id__ => {
115
+ @n1_label => true,
116
+ @n2_label => true
117
+ },
118
+ StickyFixture.__id__ => {
119
+ @s1_label => true
120
+ }
121
+ }
122
+ @set_n = @set[NoFlowFixture.__id__]
123
+ @set_s = @set[StickyFixture.__id__]
124
+ end
125
+
126
+ it 'no-ops when the label is in the set' do
127
+ Police::DataFlow::Labeling.add_label_to_set(@n1_label, @set).must_equal(
128
+ false)
129
+ @set[NoFlowFixture.__id__].__id__.must_equal @set_n.__id__
130
+ end
131
+
132
+ it 'adds labels to existing groups' do
133
+ Police::DataFlow::Labeling.add_label_to_set(@s2_label, @set).must_equal(
134
+ false)
135
+ @set[StickyFixture.__id__].__id__.must_equal @set_s.__id__
136
+ @set[StickyFixture.__id__].must_equal @s1_label => true,
137
+ @s2_label => true
138
+ end
139
+
140
+ it 'creates new groups when necessary' do
141
+ Police::DataFlow::Labeling.add_label_to_set(@h1_label, @set).must_equal(
142
+ true)
143
+ @set[HooksFlowFixture.__id__].must_equal @h1_label => true
144
+ end
145
+ end
146
+
147
+ describe '.merge_sets!' do
148
+ before do
149
+ @target = {
150
+ NoFlowFixture.__id__ => {
151
+ @n1_label => true,
152
+ @n2_label => true
153
+ },
154
+ StickyFixture.__id__ => {
155
+ @s1_label => true
156
+ }
157
+ }
158
+ @target_n = @target[NoFlowFixture.__id__]
159
+ @target_s = @target[StickyFixture.__id__]
160
+ @source = {
161
+ NoFlowFixture.__id__ => {
162
+ @n2_label => true
163
+ },
164
+ StickyFixture.__id__ => {
165
+ @s2_label => true
166
+ },
167
+ HooksFlowFixture.__id__ => {
168
+ @h1_label => true
169
+ }
170
+ }
171
+ Police::DataFlow::Labeling.merge_sets! @target, @source
172
+ end
173
+
174
+ it 'behaves when target is a superset of source' do
175
+ @target[NoFlowFixture.__id__].must_equal(
176
+ @n1_label => true, @n2_label => true)
177
+ end
178
+
179
+ it 'merges label sets' do
180
+ @target[StickyFixture.__id__].must_equal(
181
+ @s1_label => true, @s2_label => true)
182
+ end
183
+
184
+ it 'adds missing sets' do
185
+ @target[HooksFlowFixture.__id__].must_equal @h1_label => true
186
+ end
187
+
188
+ it 'does not create unnecessary objects' do
189
+ @target[NoFlowFixture.__id__].__id__.must_equal @target_n.__id__
190
+ @target[StickyFixture.__id__].__id__.must_equal @target_s.__id__
191
+ end
192
+
193
+ it 'does not reuse source objects' do
194
+ @target[HooksFlowFixture.__id__].__id__.wont_equal(
195
+ @source[HooksFlowFixture.__id__].__id__)
196
+ end
197
+ end
198
+
199
+ describe '.bulky_sticky_label' do
200
+ before do
201
+ @set = {
202
+ NoFlowFixture.__id__ => {
203
+ @n1_label => true,
204
+ @n2_label => true
205
+ },
206
+ StickyFixture.__id__ => {
207
+ @s1_label => true
208
+ }
209
+ }
210
+ @set_n = @set[NoFlowFixture.__id__]
211
+ @set_s = @set[StickyFixture.__id__]
212
+ end
213
+
214
+ describe 'with an unlabeled object' do
215
+ before do
216
+ @object = 'Hello'
217
+ @labeled = Police::DataFlow::Labeling.bulk_sticky_label @object, @set
218
+ end
219
+
220
+ it 'labels the object correctly' do
221
+ Police::DataFlow.labels(@labeled).sort_by(&:__id__).must_equal(
222
+ [@n1_label, @n2_label, @s1_label].sort_by(&:__id__))
223
+ end
224
+
225
+ it 'proxies the object correctly' do
226
+ @labeled.length.must_equal 5
227
+ @labeled[1].must_equal 'e'
228
+ end
229
+
230
+ it 'does not reuse the label set' do
231
+ @labeled.__police_labels__.__id__.wont_equal @set.__id__
232
+ @labeled.__police_stickies__.__id__.wont_equal @set.__id__
233
+ @labeled.__police_labels__[NoFlowFixture.__id__].__id__.wont_equal(
234
+ @set_n.__id__)
235
+ @labeled.__police_labels__[StickyFixture.__id__].__id__.wont_equal(
236
+ @set_s.__id__)
237
+ end
238
+ end
239
+
240
+ describe 'with a labeled object with enough groups' do
241
+ before do
242
+ @original = 'Hello'
243
+ @object = Police::DataFlow.label @original, @n1_label
244
+ @object = Police::DataFlow.label @object, @s2_label
245
+ @object = Police::DataFlow.label @object, @h1_label
246
+
247
+ @set2_n = @object.__police_labels__[NoFlowFixture.__id__]
248
+ @set2_s = @object.__police_labels__[StickyFixture.__id__]
249
+
250
+ @labeled = Police::DataFlow::Labeling.bulk_sticky_label @object, @set
251
+ end
252
+
253
+ it 'labels the object correctly' do
254
+ Police::DataFlow.labels(@labeled).sort_by(&:__id__).must_equal(
255
+ [@n1_label, @n2_label, @s1_label, @s2_label, @h1_label].
256
+ sort_by(&:__id__))
257
+ end
258
+
259
+ it 'proxies the object correctly' do
260
+ @labeled.length.must_equal 5
261
+ @labeled[1].must_equal 'e'
262
+ end
263
+
264
+ it 'reuses the proxy' do
265
+ @object.__id__.must_equal @labeled.__id__
266
+ Police::DataFlow::Labeling.proxy_class(@object).must_equal(
267
+ Police::DataFlow::Labeling.proxy_class(@labeled))
268
+ end
269
+
270
+ it 'reuses the label set groups' do
271
+ @object.__police_labels__[NoFlowFixture.__id__].__id__.must_equal(
272
+ @set2_n.__id__)
273
+ @object.__police_labels__[StickyFixture.__id__].__id__.must_equal(
274
+ @set2_s.__id__)
275
+ end
276
+ end
277
+
278
+ describe 'with a labeled object that needs a new group' do
279
+ before do
280
+ @original = 'Hello'
281
+ @object = Police::DataFlow.label @original, @n1_label
282
+ @object = Police::DataFlow.label @object, @h1_label
283
+
284
+ @set2_n = @object.__police_labels__[NoFlowFixture.__id__]
285
+
286
+ @labeled = Police::DataFlow::Labeling.bulk_sticky_label @object, @set
287
+ end
288
+
289
+ it 'labels the object correctly' do
290
+ Police::DataFlow.labels(@labeled).sort_by(&:__id__).must_equal(
291
+ [@n1_label, @n2_label, @s1_label, @h1_label].
292
+ sort_by(&:__id__))
293
+ end
294
+
295
+ it 'proxies the object correctly' do
296
+ @labeled.length.must_equal 5
297
+ @labeled[1].must_equal 'e'
298
+ end
299
+
300
+ it 'creates a new proxy' do
301
+ @object.__id__.wont_equal @labeled.__id__
302
+ Police::DataFlow::Labeling.proxy_class(@object).wont_equal(
303
+ Police::DataFlow::Labeling.proxy_class(@labeled))
304
+ end
305
+
306
+ it 'reuses label set groups when possible' do
307
+ @object.__police_labels__[NoFlowFixture.__id__].__id__.must_equal(
308
+ @set2_n.__id__)
309
+ end
310
+ end
311
+ end
312
+
313
+ describe '.dup' do
314
+ before do
315
+ @set = {
316
+ NoFlowFixture.__id__ => {
317
+ @n1_label => true,
318
+ @n2_label => true
319
+ },
320
+ StickyFixture.__id__ => {
321
+ @s1_label => true
322
+ }
323
+ }
324
+ @set_n = @set[NoFlowFixture.__id__]
325
+ @set_s = @set[StickyFixture.__id__]
326
+ @copy = Police::DataFlow::Labeling.dup_set @set
327
+ end
328
+
329
+ it 'does not change the source set' do
330
+ @set[NoFlowFixture.__id__].__id__.must_equal @set_n.__id__
331
+ @set[StickyFixture.__id__].__id__.must_equal @set_s.__id__
332
+ @set_n.must_equal @n1_label => true, @n2_label => true
333
+ @set_s.must_equal @s1_label => true
334
+ end
335
+
336
+ it 'copies the groups in the source set' do
337
+ @copy[NoFlowFixture.__id__].must_equal @n1_label => true,
338
+ @n2_label => true
339
+ @copy[StickyFixture.__id__].must_equal @s1_label => true
340
+ end
341
+
342
+ it 'does not reuse the groups in the source set' do
343
+ @copy[NoFlowFixture.__id__].__id__.wont_equal @set_n.__id__
344
+ @copy[StickyFixture.__id__].__id__.wont_equal @set_s.__id__
345
+ end
346
+
347
+ it 'does not create new groups' do
348
+ @copy.keys.must_equal [NoFlowFixture.__id__, StickyFixture.__id__]
349
+ end
350
+ end
351
+
352
+ describe '.proxy_class' do
353
+ before do
354
+ @object = 'Hello'
355
+ end
356
+
357
+ it 'returns nil for un-labeled objects' do
358
+ Police::DataFlow::Labeling.proxy_class(@object).must_equal nil
359
+ end
360
+
361
+ describe 'for proxied objects' do
362
+ before do
363
+ @labeled = Police::DataFlow.label @object, @s1_label
364
+ end
365
+
366
+ it 'returns a ProxyBase subclass' do
367
+ Police::DataFlow::Labeling.proxy_class(@labeled).superclass.must_equal(
368
+ Police::DataFlow::ProxyBase)
369
+ end
370
+
371
+ it "returns the proxy's real class" do
372
+ klass = Police::DataFlow::Labeling.proxy_class @labeled
373
+ klass.class_eval do
374
+ def boom
375
+ 'headshot'
376
+ end
377
+ end
378
+ lambda { @object.boom }.must_raise NoMethodError
379
+ @labeled.boom.must_equal 'headshot'
380
+ end
381
+ end
382
+ end
74
383
  end
@@ -4,35 +4,31 @@ describe Police::DataFlow::Proxies do
4
4
  describe '#for' do
5
5
  before do
6
6
  @label_set = {}
7
- @autoflow_set = {}
8
- Police::DataFlow::Labeling.add_label_to_set NoFlowFixture.new,
9
- @label_set, @autoflow_set
7
+ Police::DataFlow::Labeling.add_label_to_set NoFlowFixture.new, @label_set
10
8
  end
11
-
9
+
12
10
  let(:result) do
13
11
  Police::DataFlow::Proxies.for ProxyingFixture, @label_set
14
12
  end
15
13
  after { Police::DataFlow::Proxies.clear_cache }
16
-
14
+
17
15
  it 'creates a Police::DataFlow::ProxyBase subclass' do
18
16
  result.superclass.must_equal Police::DataFlow::ProxyBase
19
17
  end
20
-
18
+
21
19
  it 'caches classes' do
22
20
  Police::DataFlow::Proxies.for(ProxyingFixture, @label_set).
23
21
  must_equal result
24
22
  end
25
-
23
+
26
24
  it 'creates different proxies for different classes' do
27
25
  Police::DataFlow::Proxies.for(Class.new(ProxyingFixture), @label_set).
28
26
  wont_equal result
29
27
  end
30
-
28
+
31
29
  it 'creates different proxies for sets of different label classes' do
32
30
  label_set = @label_set.clone
33
- autoflow_set = @autoflow_set.clone
34
- Police::DataFlow::Labeling.add_label_to_set AutoFlowFixture.new,
35
- label_set, autoflow_set
31
+ Police::DataFlow::Labeling.add_label_to_set StickyFixture.new, label_set
36
32
  Police::DataFlow::Proxies.for(ProxyingFixture, label_set).
37
33
  wont_equal result
38
34
  end