woyo-world 0.0.5 → 0.0.6

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.
@@ -17,14 +17,43 @@ describe Woyo::Attributes do
17
17
  end
18
18
 
19
19
  it 'hash of names and values can be retrieved for instance' do
20
- attrs = AttrTest.new.attributes
21
- attrs.should be_instance_of Hash
20
+ attr_test = AttrTest.new
21
+ attr_test.attributes.should be_instance_of Woyo::Attributes::AttributesHash
22
+ AttrTest.attributes.each do |attr|
23
+ attr_test.send(attr, attr.to_s.upcase)
24
+ end
25
+ attr_test.attributes.keys.should eq [ :attr1, :attr2, :attr3 ]
26
+ attr_test.attributes.values.should eq [ 'ATTR1', 'ATTR2', 'ATTR3' ]
27
+ end
28
+
29
+ it 'hash of names and nil values can be retrieved for instance before populating' do
30
+ attr_test = AttrTest.new
31
+ attr_test.attributes.should be_instance_of Woyo::Attributes::AttributesHash
32
+ attr_test.attributes.keys.should eq [ :attr1, :attr2, :attr3 ]
33
+ attr_test.attributes.values.should eq [ nil, nil, nil ]
34
+ end
35
+
36
+ it 'hash of names and default values can be retrieved for instance before populating' do
37
+ expect {
38
+ class DefTest
39
+ include Woyo::Attributes
40
+ attributes one: 1, two: 2, three: proc { 3 }
41
+ end
42
+ }.to_not raise_error
43
+ def_test = DefTest.new
44
+ def_test.attributes.keys.should eq [ :one, :two, :three ]
45
+ def_test.attributes.values.should eq [ 1, 2, 3 ]
46
+ end
47
+
48
+ it 'have convenience accessor :names for :keys' do
49
+ attr_test = AttrTest.new
50
+ attr_test.attributes.names.should eq [ :attr1, :attr2, :attr3 ]
22
51
  end
23
52
 
24
53
  it 'can be written via method with =' do
25
54
  attr_test = AttrTest.new
26
55
  AttrTest.attributes.each do |attr|
27
- attr_test.send(attr, attr.to_s.upcase)
56
+ attr_test.send("#{attr}=", attr.to_s.upcase)
28
57
  end
29
58
  attr_test.attributes.count.should eq AttrTest.attributes.count
30
59
  attr_test.attributes.each do |name,value|
@@ -62,13 +91,24 @@ describe Woyo::Attributes do
62
91
  }.to_not raise_error
63
92
  AttrTest.attributes.count.should eq 6
64
93
  attr_test = AttrTest.new
65
- # populate attributes
66
94
  AttrTest.attributes.each do |attr|
67
95
  attr_test.send(attr, attr.to_s.upcase)
68
96
  end
69
97
  attr_test.attributes.count.should eq 6
70
98
  end
71
99
 
100
+ it 'can be defined with "attribute"' do
101
+ expect {
102
+ class AttrTest
103
+ attribute :open
104
+ end
105
+ }.to_not raise_error
106
+ attr_test = AttrTest.new
107
+ attr_test.open.should be_nil
108
+ attr_test.open = true
109
+ attr_test.open.should be_true
110
+ end
111
+
72
112
  it 'can have a default value' do
73
113
  expect {
74
114
  class AttrTest
@@ -143,5 +183,319 @@ describe Woyo::Attributes do
143
183
  attr_test.attr_with_lambda_default.should eq "okay"
144
184
  end
145
185
 
186
+ context 'that are boolean' do
187
+
188
+ context 'have convenient instance accessors' do
189
+
190
+ before :all do
191
+ expect {
192
+ class BooleanAttrTest
193
+ include Woyo::Attributes
194
+ attribute open: true
195
+ attribute light: false
196
+ end
197
+ }.to_not raise_error
198
+ end
199
+
200
+ it '#attr?' do
201
+ attr_test = BooleanAttrTest.new
202
+ attr_test.open.should eq true
203
+ attr_test.open?.should eq true
204
+ end
205
+
206
+ it '#attr!' do
207
+ attr_test = BooleanAttrTest.new
208
+ attr_test.open = false
209
+ attr_test.open.should eq false
210
+ attr_test.open!.should eq true
211
+ attr_test.open.should eq true
212
+ end
213
+
214
+ it '#is? :attr' do
215
+ attr_test = BooleanAttrTest.new
216
+ attr_test.is?(:open).should eq true
217
+ attr_test.open = false
218
+ attr_test.is?(:open).should eq false
219
+ end
220
+
221
+ it '#is :attr' do
222
+ attr_test = BooleanAttrTest.new
223
+ attr_test.light.should eq false
224
+ attr_test.is(:light)
225
+ attr_test.light.should eq true
226
+ end
227
+ end
228
+
229
+ context 'have class accessor ::is' do
230
+
231
+ # I was confused here, this may not be needed as a class method at all!!!
232
+
233
+ it 'that defines new attribute with true default' do
234
+ expect {
235
+ class BooleanIsTest1
236
+ include Woyo::Attributes
237
+ is :attr1
238
+ end
239
+ }.to_not raise_error
240
+ attr_test = BooleanIsTest1.new
241
+ attr_test.attr1.should eq true
242
+ end
243
+
244
+ it 'that sets true default for existing attribute' do
245
+ expect {
246
+ class BooleanIsTest2
247
+ include Woyo::Attributes
248
+ attribute :attr2
249
+ is :attr2
250
+ end
251
+ }.to_not raise_error
252
+ attr_test = BooleanIsTest2.new
253
+ attr_test.attr2.should eq true
254
+ end
255
+
256
+ it 'that changes default to true for existing attribute' do
257
+ expect {
258
+ class BooleanIsTest3
259
+ include Woyo::Attributes
260
+ attribute :attr3 => false
261
+ is :attr3
262
+ end
263
+ }.to_not raise_error
264
+ attr_test = BooleanIsTest3.new
265
+ attr_test.attr3.should eq true
266
+ end
267
+
268
+ it 'that works for attribute in BooleanGroup' do
269
+ expect {
270
+ class BooleanIsTest4
271
+ include Woyo::Attributes
272
+ group! :temp, :hot, :warm, :cool, :cold
273
+ # :hot is true by default
274
+ is :cold
275
+ # :cold is now true
276
+ end
277
+ }.to_not raise_error
278
+ attr_test = BooleanIsTest4.new
279
+ attr_test.hot.should eq false
280
+ attr_test.warm.should eq false
281
+ attr_test.cool.should eq false
282
+ attr_test.cold.should eq true
283
+ end
284
+
285
+ end
286
+
287
+ end
288
+
289
+ context 'can be re-defined' do
290
+
291
+ it 'without duplication' do
292
+ expect {
293
+ class AttrReDef1
294
+ include Woyo::Attributes
295
+ attribute :attr1
296
+ end
297
+ class AttrReDef1
298
+ attribute :attr1
299
+ end
300
+ }.to_not raise_error
301
+ AttrReDef1.attributes.count.should eq 1
302
+ AttrReDef1.attributes.should eq [:attr1]
303
+ attr_rd1 = AttrReDef1.new
304
+ attr_rd1.attr1.should be_nil
305
+ end
306
+
307
+ it 'to set default' do
308
+ expect {
309
+ class AttrReDef2
310
+ include Woyo::Attributes
311
+ attribute :attr2
312
+ end
313
+ class AttrReDef2
314
+ attribute attr2: 'two'
315
+ end
316
+ }.to_not raise_error
317
+ AttrReDef2.attributes.count.should eq 1
318
+ AttrReDef2.attributes.should eq [:attr2]
319
+ attr_rd2 = AttrReDef2.new
320
+ attr_rd2.attr2.should eq 'two'
321
+ end
322
+
323
+ it 'to change default' do
324
+ expect {
325
+ class AttrReDef3
326
+ include Woyo::Attributes
327
+ attribute attr3: '333'
328
+ end
329
+ class AttrReDef3
330
+ attribute attr3: 'three'
331
+ end
332
+ }.to_not raise_error
333
+ AttrReDef3.attributes.count.should eq 1
334
+ AttrReDef3.attributes.should eq [:attr3]
335
+ attr_rd3 = AttrReDef3.new
336
+ attr_rd3.attr3.should eq 'three'
337
+ end
338
+
339
+ end
340
+
341
+ context 'groups' do
342
+
343
+ before :all do
344
+ class AT
345
+ include Woyo::Attributes
346
+ group :stooges, :larry, :curly, :moe
347
+ group :cars, :mustang, :ferarri, :mini
348
+ end
349
+ @at = AT.new
350
+ end
351
+
352
+ it 'can be listed for class' do
353
+ groups = AT.groups
354
+ groups.should be_instance_of Hash
355
+ groups.count.should eq 2
356
+ groups.keys.should eq [ :stooges, :cars ]
357
+ groups[:stooges].should eq [ :larry, :curly, :moe ]
358
+ groups[:cars].should eq [ :mustang, :ferarri, :mini ]
359
+ end
360
+
361
+ it 'have convenience accessor :names for :keys' do
362
+ @at.stooges.names.should eq [ :larry, :curly, :moe ]
363
+ end
364
+
365
+ it 'names and nil values can be retrieved from instance without populating' do
366
+ @at.stooges.should be_instance_of Woyo::Attributes::Group
367
+ @at.stooges.count.should eq 3
368
+ @at.stooges.names.should eq [ :larry, :curly, :moe ]
369
+ @at.stooges.values.should eq [ nil, nil, nil ]
370
+ end
371
+
372
+ it 'names and default values can be retrieved from instance without populating' do
373
+ expect {
374
+ class GroupDefTest
375
+ include Woyo::Attributes
376
+ group :numbers, one: 1, two: 2, three: proc { 3 }
377
+ end
378
+ }.to_not raise_error
379
+ def_test = GroupDefTest.new
380
+ groups = def_test.groups
381
+ groups.should be_instance_of Hash
382
+ groups.count.should eq 1
383
+ groups.names.should eq [ :numbers ]
384
+ groups[:numbers].should be_instance_of Woyo::Attributes::Group
385
+ groups[:numbers].names.should eq [ :one, :two, :three ]
386
+ groups[:numbers].values.should eq [ 1, 2, 3 ]
387
+ def_test.numbers.names.should eq [ :one, :two, :three ]
388
+ def_test.numbers.values.should eq [ 1, 2, 3 ]
389
+ end
390
+
391
+ it 'members can be accessed via group' do
392
+ @at.stooges[:curly].should eq nil
393
+ @at.stooges[:curly] = 'bald'
394
+ @at.stooges[:curly].should eq 'bald'
395
+ end
396
+
397
+ it 'members are also attributes' do
398
+ all_attrs = [ :larry, :curly, :moe, :mustang, :ferarri, :mini ]
399
+ @at.attributes.keys.should eq all_attrs
400
+ all_attrs.each do |attr|
401
+ @at.should respond_to attr
402
+ end
403
+ end
404
+
405
+ it 'members are attributes' do
406
+ @at.stooges[:moe] = 'knucklehead'
407
+ @at.stooges[:moe].should eq 'knucklehead'
408
+ @at.moe.should eq 'knucklehead'
409
+ end
410
+
411
+ it 'attributes are members' do
412
+ @at.ferarri = 'fast'
413
+ @at.ferarri.should eq 'fast'
414
+ @at.cars[:ferarri].should eq 'fast'
415
+ end
416
+
417
+ end
418
+
419
+ context 'boolean groups' do
420
+
421
+ before :all do
422
+ class ExGroupTest
423
+ include Woyo::Attributes
424
+ group! :temp, :hot, :warm, :cool, :cold
425
+ group! :light, :dark, :dim, :bright
426
+ end
427
+ end
428
+
429
+ it 'are listed for a class' do
430
+ groups = ExGroupTest.boolean_groups
431
+ groups.should be_instance_of Hash
432
+ groups.count.should eq 2
433
+ groups.keys.should eq [ :temp, :light ]
434
+ groups[:temp].should eq [ :hot, :warm, :cool, :cold ]
435
+ groups[:light].should eq [ :dark, :dim, :bright ]
436
+ end
437
+
438
+ it 'accessor returns BooleanGroup instance' do
439
+ egt = ExGroupTest.new
440
+ egt.temp.should be_instance_of Woyo::Attributes::BooleanGroup
441
+ end
442
+
443
+ it 'first member is true, rest are false' do
444
+ egt = ExGroupTest.new
445
+ egt.light[:dark].should eq true
446
+ egt.light[:dim].should eq false
447
+ egt.light[:bright].should eq false
448
+ end
449
+
450
+ it 'making group member true affects member attributes' do
451
+ egt = ExGroupTest.new
452
+ egt.temp[:cold] = true
453
+ egt.cold.should be true
454
+ egt.cool.should be false
455
+ egt.warm.should be false
456
+ egt.hot.should be false
457
+ end
458
+
459
+ it 'making attribute true affects group members' do
460
+ egt = ExGroupTest.new
461
+ egt.cold = true
462
+ egt.light[:cold].should be true
463
+ egt.light[:cool].should be false
464
+ egt.light[:warm].should be false
465
+ egt.light[:hot].should be false
466
+ end
467
+
468
+ end
469
+
470
+ context 'assigned a Hash as a value' do
471
+
472
+ before :all do
473
+ class AttrHashTest
474
+ include Woyo::Attributes
475
+ attributes :reaction, :hot, :cold
476
+ end
477
+ @aht = AttrHashTest.new
478
+ end
479
+
480
+ it 'accepts the hash as a value' do
481
+ expect { @aht.reaction hot: 'Sweat', cold: 'Shiver' }.to_not raise_error
482
+ end
483
+
484
+ it 'returns the value of the first key that evaluates as a true attribute' do
485
+ @aht.cold = true
486
+ @aht.reaction.should eq 'Shiver'
487
+ @aht.hot = true
488
+ @aht.reaction.should eq 'Sweat'
489
+ end
490
+
491
+ it 'otherwise it returns the hash' do
492
+ reactions = { :hot => 'Sweat', :cold => 'Shiver' }
493
+ @aht.cold = false
494
+ @aht.hot = false
495
+ @aht.reaction.should eq reactions
496
+ end
497
+
498
+ end
499
+
146
500
  end
147
501
 
@@ -0,0 +1,162 @@
1
+ require 'woyo/world/group'
2
+
3
+ describe Woyo::Attributes::AttributesHash do
4
+
5
+ before :all do
6
+ @attributes = Woyo::Attributes::AttributesHash.new
7
+ class Listener
8
+ attr_reader :notified, :attr, :value
9
+ def initialize
10
+ @notified = false
11
+ end
12
+ def notify attr, value
13
+ @notified = true
14
+ @attr = attr
15
+ @value = value
16
+ end
17
+ end
18
+ @listener = Listener.new
19
+ end
20
+
21
+ it 'is a kind of hash' do
22
+ @attributes.should be_kind_of Hash
23
+ @attributes[:test].should be nil
24
+ @attributes[:test] = true
25
+ @attributes[:test].should be true
26
+ end
27
+
28
+ it 'provides list of attribute names' do
29
+ @attributes.names.should eq [:test]
30
+ end
31
+
32
+ it 'registers attribute listeners' do
33
+ @attributes.add_attribute_listener :test, @listener
34
+ end
35
+
36
+ it 'maintains list of attribute listeners' do
37
+ @attributes.listeners.should be_kind_of Hash
38
+ @attributes.listeners[:test].should be @listener
39
+ end
40
+
41
+ it 'notifies listeners of attribute change' do
42
+ @listener.notified.should be false
43
+ @listener.attr.should be nil
44
+ @listener.value.should be nil
45
+ @attributes[:test] = :new_value
46
+ @listener.notified.should eq true
47
+ @listener.attr.should eq :test
48
+ @listener.value.should eq :new_value
49
+ end
50
+
51
+ it 'does not notify listener if attribute does not change' do
52
+ @attributes[:test] = :same_value
53
+ @listener = Listener.new
54
+ @attributes.add_attribute_listener :test, @listener
55
+ @listener.notified.should be false
56
+ @attributes[:test] = :same_value
57
+ @listener.notified.should be false
58
+ end
59
+
60
+ end
61
+
62
+ describe Woyo::Attributes::Group do
63
+
64
+ before :all do
65
+ @attributes = Woyo::Attributes::AttributesHash.new
66
+ @group = Woyo::Attributes::Group.new @attributes, :larry, :curly, :moe
67
+ end
68
+
69
+ it '#initialize requires attributes object' do
70
+ expect { Woyo::Attributes::Group.new @attributes, :larry, :curly, :moe }.to_not raise_error
71
+ expect { Woyo::Attributes::Group.new }.to raise_error
72
+ end
73
+
74
+ it 'maintains list of members' do
75
+ @group.members.should eq [ :larry, :curly, :moe ]
76
+ end
77
+
78
+ it 'member names can be listed' do
79
+ @group.names.should eq [ :larry, :curly, :moe ]
80
+ end
81
+
82
+ it 'members are backed by attributes' do
83
+ @group[:larry] = 'dumb'
84
+ @group[:curly] = 'bald'
85
+ @group[:moe] = 'smart'
86
+ @group[:larry].should eq 'dumb'
87
+ @group[:curly].should eq 'bald'
88
+ @group[:moe].should eq 'smart'
89
+ @attributes[:larry].should eq 'dumb'
90
+ @attributes[:curly].should eq 'bald'
91
+ @attributes[:moe].should eq 'smart'
92
+ end
93
+
94
+ it 'member values can be listed' do
95
+ @group.values.should eq %w( dumb bald smart )
96
+ end
97
+
98
+ end
99
+
100
+ describe Woyo::Attributes::BooleanGroup do
101
+
102
+ before :all do
103
+ @group = Woyo::Attributes::BooleanGroup.new Woyo::Attributes::AttributesHash.new, :warm, :cool, :cold
104
+ end
105
+
106
+ it 'has default' do
107
+ @group.default.should eq :warm
108
+ end
109
+
110
+ it 'defaults to first member true, the rest false' do
111
+ @group[:warm].should be true
112
+ @group[:cool].should be false
113
+ @group[:cold].should be false
114
+ end
115
+
116
+ it 'registers as listener for attributes' do
117
+ @group.members.each do |member|
118
+ @group.attributes.listeners[member].should be @group
119
+ end
120
+ end
121
+
122
+ it 'setting a member true changes the rest to false' do
123
+ @group[:cold] = true
124
+ @group[:warm].should be false
125
+ @group[:cool].should be false
126
+ @group[:cold].should be true
127
+ end
128
+
129
+ it 'for a group > 2 members setting a true member false reverts to default' do
130
+ @group[:cold] = false
131
+ @group[:warm].should be true
132
+ @group[:cool].should be false
133
+ @group[:cold].should be false
134
+ end
135
+
136
+ it 'for a binary group setting a true member false sets the other true' do
137
+ @binary_group = Woyo::Attributes::BooleanGroup.new Woyo::Attributes::AttributesHash.new, :yes, :no
138
+ @binary_group[:yes].should be true
139
+ @binary_group[:no].should be false
140
+ @binary_group[:yes] = false
141
+ @binary_group[:yes].should be false
142
+ @binary_group[:no].should be true
143
+ end
144
+
145
+ it 'can only set existing members' do
146
+ expect { @group[:bogus] = true }.to raise_error
147
+ end
148
+
149
+ it 'can be reset to default!' do
150
+ @group[:cool] = true
151
+ @group.default!
152
+ @group[:warm].should eq true
153
+ end
154
+
155
+ it '#value returns name of true member' do
156
+ @group[:warm] = true
157
+ @group.value.should eq :warm
158
+ @group[:cold] = true
159
+ @group.value.should eq :cold
160
+ end
161
+
162
+ end