woyo-world 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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