woyo-world 0.0.8 → 0.0.9
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.
- checksums.yaml +4 -4
- data/lib/woyo/world/action.rb +18 -6
- data/lib/woyo/world/attributes.rb +42 -5
- data/lib/woyo/world/group.rb +2 -2
- data/lib/woyo/world/version.rb +1 -1
- data/lib/woyo/world/way.rb +14 -4
- data/lib/woyo/world/world.rb +2 -2
- data/lib/woyo/world/world_object.rb +39 -2
- data/spec/spec_doc.haml +15 -18
- data/spec/spec_doc_formatter.rb +1 -1
- data/spec/woyo/dsl/dsl_spec.rb +12 -16
- data/spec/woyo/world/action_spec.rb +42 -18
- data/spec/woyo/world/attributes_spec.rb +105 -0
- data/spec/woyo/world/group_spec.rb +16 -5
- data/spec/woyo/world/location_spec.rb +61 -10
- data/spec/woyo/world/way_spec.rb +2 -2
- data/spec/woyo/world/world_object_spec.rb +102 -3
- data/spec/woyo/world/world_spec.rb +10 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75a8fb38d8b692c8197acee596c314f553268d8c
|
4
|
+
data.tar.gz: b286b86791f363c9195cc7bb17536837f77bfe5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 528d74579d0b790a09202b6a672c1de363d2369ee7b40a74e0c0f916c3668129a304184c2b37f88f4fdb6cfd71623f3ddaf1e4341b5fe20a6d39faee2803e97d
|
7
|
+
data.tar.gz: 8e4f7ee050063b42905ed304185d5394d7064dcd3fc424b5105459e81b20d4ff9e704b224e20038a9125684dc815eb1066d5a9c53b33c0c293df1fae94a9f3ff
|
data/lib/woyo/world/action.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'world_object'
|
2
|
+
require_relative 'location'
|
2
3
|
|
3
4
|
module Woyo
|
4
5
|
|
@@ -7,20 +8,22 @@ class Action < WorldObject
|
|
7
8
|
def initialize_object
|
8
9
|
super
|
9
10
|
attribute :describe
|
10
|
-
exclusion :result
|
11
11
|
@proc = proc { nil }
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute
|
15
|
-
|
15
|
+
location_or_context.clear_changes
|
16
|
+
result = if @proc.arity < 1
|
16
17
|
@context.instance_eval &@proc
|
17
18
|
else
|
18
19
|
@context.instance_exec self, &@proc
|
19
20
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
unless result.kind_of? Hash
|
22
|
+
result = { return: result }
|
23
|
+
end
|
24
|
+
# result: { location: :place } signals change of location (like going a way!)
|
25
|
+
# todo: fill return hash with action attributes, groups, exclusions ? ...
|
26
|
+
{ describe: describe, result: result, changes: location_or_context.changes }
|
24
27
|
end
|
25
28
|
|
26
29
|
def execution &block
|
@@ -31,6 +34,15 @@ class Action < WorldObject
|
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
37
|
+
def location_or_context
|
38
|
+
ancestor = self
|
39
|
+
while ancestor.context do
|
40
|
+
return ancestor if ancestor.kind_of? Woyo::Location
|
41
|
+
ancestor = ancestor.context
|
42
|
+
end
|
43
|
+
ancestor
|
44
|
+
end
|
45
|
+
|
34
46
|
end
|
35
47
|
|
36
48
|
end
|
@@ -19,20 +19,57 @@ module Attributes
|
|
19
19
|
@listeners = {}
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
@listeners[attr]
|
22
|
+
def add_listener attr, listener
|
23
|
+
@listeners[attr] ||= []
|
24
|
+
@listeners[attr] << listener
|
24
25
|
end
|
25
26
|
|
26
27
|
def []= attr, value
|
27
28
|
old_value = self[attr]
|
28
29
|
super
|
29
|
-
if
|
30
|
-
listener.notify attr, value
|
30
|
+
if value != old_value
|
31
|
+
@listeners[attr].each { |listener| listener.notify attr, value } if @listeners[attr] # attribute listeners (groups, etc..)
|
32
|
+
@listeners[:*].each { |listener| listener.notify attr, value } if @listeners[:*] # wildcard listeners (trackers)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
36
|
end
|
35
|
-
|
37
|
+
|
38
|
+
class ChangesHash < Hash
|
39
|
+
|
40
|
+
alias_method :names, :keys
|
41
|
+
alias_method :set, :[]=
|
42
|
+
|
43
|
+
def notify attr, value
|
44
|
+
self[attr] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def changes
|
50
|
+
@changes ? @changes.merge!( dependent_changes ) : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def dependent_changes
|
54
|
+
remaining_attrs = @attributes.names - @changes.names
|
55
|
+
dependent_attrs = remaining_attrs.select do |attr|
|
56
|
+
@attributes[attr].kind_of?( Hash ) && ! ( @attributes[attr].keys & @changes.names ).empty?
|
57
|
+
end
|
58
|
+
dependent_attrs.each_with_object({}) do |attr,hash|
|
59
|
+
hash[attr] = send attr
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def track_changes
|
64
|
+
@changes = ChangesHash.new
|
65
|
+
@attributes ||= Woyo::Attributes::AttributesHash.new
|
66
|
+
@attributes.add_listener :*, @changes # :* indicates listener for changes to all attributes
|
67
|
+
end
|
68
|
+
|
69
|
+
def clear_changes
|
70
|
+
@changes.clear
|
71
|
+
end
|
72
|
+
|
36
73
|
def attribute *attrs, &block
|
37
74
|
attributes *attrs, &block
|
38
75
|
end
|
data/lib/woyo/world/group.rb
CHANGED
@@ -38,7 +38,7 @@ module Attributes
|
|
38
38
|
if @members && ! @members.empty?
|
39
39
|
@default = @members.first
|
40
40
|
self[@default] = true
|
41
|
-
@members.each { |member| @attributes.
|
41
|
+
@members.each { |member| @attributes.add_listener member, self }
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -51,7 +51,7 @@ module Attributes
|
|
51
51
|
else
|
52
52
|
@attributes.set new_member, false
|
53
53
|
end
|
54
|
-
@attributes.
|
54
|
+
@attributes.add_listener new_member, self
|
55
55
|
self
|
56
56
|
end
|
57
57
|
|
data/lib/woyo/world/version.rb
CHANGED
data/lib/woyo/world/way.rb
CHANGED
@@ -8,8 +8,22 @@ class Way < WorldObject
|
|
8
8
|
super
|
9
9
|
attribute :going
|
10
10
|
exclusion :passable, :closed, :open # defaults to closed: true
|
11
|
+
action :go do
|
12
|
+
describe proc { self.context.going }
|
13
|
+
#result proc { self.context.passable }
|
14
|
+
execution do
|
15
|
+
{
|
16
|
+
go: open?,
|
17
|
+
location: open? ? self.to.id : nil
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
11
21
|
end
|
12
22
|
|
23
|
+
# def go
|
24
|
+
# { go: open?, going: self.going }
|
25
|
+
# end
|
26
|
+
|
13
27
|
def world
|
14
28
|
from ? from.world : nil
|
15
29
|
end
|
@@ -48,10 +62,6 @@ class Way < WorldObject
|
|
48
62
|
end
|
49
63
|
end
|
50
64
|
|
51
|
-
def go
|
52
|
-
{ go: open?, going: self.going }
|
53
|
-
end
|
54
|
-
|
55
65
|
end
|
56
66
|
|
57
67
|
end
|
data/lib/woyo/world/world.rb
CHANGED
@@ -14,15 +14,52 @@ class WorldObject
|
|
14
14
|
children :action
|
15
15
|
|
16
16
|
def initialize id, context: nil, &block
|
17
|
-
@id = id.to_s.downcase.to_sym
|
17
|
+
@id = id ? id.to_s.downcase.to_sym : nil
|
18
18
|
@context = context
|
19
|
-
attributes :description, name: proc { id.to_s.capitalize }
|
19
|
+
attributes :description, name: proc { id.to_s.capitalize.gsub('_',' ') }
|
20
20
|
initialize_object
|
21
21
|
evaluate &block
|
22
|
+
# todo:
|
23
|
+
# creating attributes should register with change listener
|
24
|
+
# this will catch all attributes anytime they are created
|
25
|
+
# instead of just after initialize->evaluate
|
26
|
+
track_changes
|
22
27
|
end
|
23
28
|
|
24
29
|
def initialize_object ; end
|
25
30
|
|
31
|
+
def uid
|
32
|
+
if @context
|
33
|
+
@context.uid + '-' + id.to_s
|
34
|
+
else
|
35
|
+
id.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :attribute_clear_changes, :clear_changes
|
40
|
+
def clear_changes
|
41
|
+
attribute_clear_changes
|
42
|
+
children.each do |child_type,type_children|
|
43
|
+
type_children.each do |child_id,child|
|
44
|
+
child.clear_changes
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
alias_method :attribute_changes, :changes
|
50
|
+
def changes
|
51
|
+
all_changes = attribute_changes
|
52
|
+
children.each do |child_type,type_children|
|
53
|
+
child_type_changes = {}
|
54
|
+
type_children.each do |child_id,child|
|
55
|
+
child_changes = child.changes
|
56
|
+
child_type_changes[child_id] = child_changes unless child_changes.empty?
|
57
|
+
end
|
58
|
+
all_changes[child_type] = child_type_changes unless child_type_changes.empty?
|
59
|
+
end
|
60
|
+
all_changes
|
61
|
+
end
|
62
|
+
|
26
63
|
end
|
27
64
|
|
28
65
|
end
|
data/spec/spec_doc.haml
CHANGED
@@ -9,24 +9,22 @@
|
|
9
9
|
|
10
10
|
- def render_group group_element
|
11
11
|
- group = group_element.values.first
|
12
|
-
-
|
13
|
-
-
|
14
|
-
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
- when element.keys.first == :example then render_example element
|
12
|
+
- haml_tag :div do
|
13
|
+
- group.each do |element|
|
14
|
+
- case
|
15
|
+
- when element.keys.first == :head then render_head element, 2
|
16
|
+
- when element.keys.first == :text then render_text element
|
17
|
+
- when element.keys.first == :group then render_group element
|
18
|
+
- when element.keys.first == :example then render_example element
|
20
19
|
|
21
20
|
- def render_example example_element
|
22
21
|
- example = example_element.values.first
|
23
|
-
-
|
24
|
-
-
|
25
|
-
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
- when element.keys.include?(:code) then render_code element
|
22
|
+
- haml_tag :div do
|
23
|
+
- example.each do |element|
|
24
|
+
- case
|
25
|
+
- when element.keys.first == :head then render_head element, 3
|
26
|
+
- when element.keys.first == :text then render_text element
|
27
|
+
- when element.keys.include?(:code) then render_code element
|
30
28
|
|
31
29
|
- def render_head head_element, size = 1
|
32
30
|
- case size
|
@@ -41,9 +39,8 @@
|
|
41
39
|
- haml_tag :p, text_element.values.first
|
42
40
|
|
43
41
|
- def render_code code_element
|
44
|
-
-
|
45
|
-
- haml_tag :
|
46
|
-
- haml_tag :pre, "<code>#{preserve(code_element[:code])}#{' #=> ' + code_element[:value].to_s if code_element[:value]}</code>"
|
42
|
+
- haml_tag :div do
|
43
|
+
- haml_tag :pre, "<code>#{preserve(code_element[:code])}#{' #=> ' + code_element[:value].to_s if code_element[:value]}</code>"
|
47
44
|
|
48
45
|
%html
|
49
46
|
|
data/spec/spec_doc_formatter.rb
CHANGED
data/spec/woyo/dsl/dsl_spec.rb
CHANGED
@@ -219,10 +219,9 @@ describe 'DSL' do
|
|
219
219
|
|
220
220
|
head 'Items'
|
221
221
|
|
222
|
-
doc 'stuff here'
|
223
|
-
|
224
|
-
|
225
|
-
# end
|
222
|
+
doc 'stuff here' do
|
223
|
+
pending
|
224
|
+
end
|
226
225
|
|
227
226
|
end
|
228
227
|
|
@@ -310,20 +309,17 @@ describe 'DSL' do
|
|
310
309
|
head 'Context'
|
311
310
|
text "Other objects may be referred to in different ways."
|
312
311
|
|
313
|
-
doc 'world'
|
314
|
-
|
315
|
-
|
316
|
-
# end
|
312
|
+
doc 'world' do
|
313
|
+
pending
|
314
|
+
end
|
317
315
|
|
318
|
-
doc 'location'
|
319
|
-
|
320
|
-
|
321
|
-
# end
|
316
|
+
doc 'location' do
|
317
|
+
pending
|
318
|
+
end
|
322
319
|
|
323
|
-
doc 'context'
|
324
|
-
|
325
|
-
|
326
|
-
# end
|
320
|
+
doc 'context' do
|
321
|
+
pending
|
322
|
+
end
|
327
323
|
|
328
324
|
end
|
329
325
|
|
@@ -5,21 +5,21 @@ describe Woyo::Action do
|
|
5
5
|
|
6
6
|
let( :action ) { Woyo::Action.new :test }
|
7
7
|
|
8
|
-
context 'has exclusions' do
|
8
|
+
# context 'has exclusions' do
|
9
9
|
|
10
|
-
|
10
|
+
# context ':result' do
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# it 'exists' do
|
13
|
+
# expect(action.exclusions.names).to include :result
|
14
|
+
# end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
# it 'has no members' do
|
17
|
+
# expect(action.result.members).to be_empty
|
18
|
+
# end
|
19
19
|
|
20
|
-
|
20
|
+
# end
|
21
21
|
|
22
|
-
end
|
22
|
+
# end
|
23
23
|
|
24
24
|
context "execution may be defined" do
|
25
25
|
|
@@ -30,7 +30,7 @@ describe Woyo::Action do
|
|
30
30
|
|
31
31
|
end
|
32
32
|
|
33
|
-
context "
|
33
|
+
context "executed" do
|
34
34
|
|
35
35
|
it 'by calling #execution directly' do
|
36
36
|
action.execution { :answer }
|
@@ -47,14 +47,14 @@ describe Woyo::Action do
|
|
47
47
|
|
48
48
|
it 'returns result hash with single values for single truthy result' do
|
49
49
|
action.exclusion :result, :success, :failure
|
50
|
-
action.execution { |
|
50
|
+
action.execution { |action| action.success! }
|
51
51
|
action.describe success: "Succeeded"
|
52
|
-
expect(action.execute).to eq( { result: :success, describe: "Succeeded", execution: true } )
|
52
|
+
expect(action.execute).to eq( { result: :success, describe: "Succeeded", execution: true, changes: {} } )
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'returns result hash with empty results for empty result exclusion' do
|
56
56
|
action.describe "Empty"
|
57
|
-
expect(action.execute).to eq( { result: nil, describe: "Empty", execution: nil } )
|
57
|
+
expect(action.execute).to eq( { result: nil, describe: "Empty", execution: nil, changes: {} } )
|
58
58
|
end
|
59
59
|
|
60
60
|
end
|
@@ -64,24 +64,48 @@ describe Woyo::Action do
|
|
64
64
|
it 'returns result hash with single value for single truthy result' do
|
65
65
|
action.group :result, a: false, b: true, c: false
|
66
66
|
action.describe a: 'aaa', b: 'bbb', c: 'ccc'
|
67
|
-
expect(action.execute).to eq( { result: :b, describe: 'bbb', execution: nil } )
|
67
|
+
expect(action.execute).to eq( { result: :b, describe: 'bbb', execution: nil, changes: {} } )
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'returns result hash with multiple values for multiple truthy results' do
|
71
71
|
action.group :result, a: true, b: false, c: true
|
72
72
|
action.describe a: 'aaa', b: 'bbb', c: 'ccc'
|
73
|
-
expect(action.execute).to eq( { result: [ :a, :c ], describe: [ 'aaa', 'ccc' ], execution: nil } )
|
73
|
+
expect(action.execute).to eq( { result: [ :a, :c ], describe: [ 'aaa', 'ccc' ], execution: nil, changes: {} } )
|
74
74
|
end
|
75
75
|
|
76
76
|
it 'returns result hash with empty results for empty result group' do
|
77
77
|
action.describe "Empty"
|
78
|
-
expect(action.execute).to eq( { result: nil, describe: "Empty", execution: nil } )
|
78
|
+
expect(action.execute).to eq( { result: nil, describe: "Empty", execution: nil, changes: {} } )
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'returns result hash with empty results for no truthy results' do
|
82
82
|
action.group :result, a: false, b: false, c: false
|
83
83
|
action.describe "Empty"
|
84
|
-
expect(action.execute).to eq( { result: nil, describe: "Empty", execution: nil } )
|
84
|
+
expect(action.execute).to eq( { result: nil, describe: "Empty", execution: nil, changes: {} } )
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with changes' do
|
90
|
+
|
91
|
+
it 'returns changed attributes' do
|
92
|
+
action.attributes :a, :b ,:c
|
93
|
+
action.execution { |action| action.a true ; action.b false }
|
94
|
+
expect(action.execute[:changes]).to eq( { a: true, b: false } )
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns changed attributes for this execution only' do
|
98
|
+
action.attributes :a, :b ,:count
|
99
|
+
action.execution do |action|
|
100
|
+
action.count ||= 0
|
101
|
+
action.count += 1
|
102
|
+
case action.count
|
103
|
+
when 1 then action.a true
|
104
|
+
when 2 then action.b true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
expect(action.execute[:changes]).to eq( { count: 1, a: true } )
|
108
|
+
expect(action.execute[:changes]).to eq( { count: 2, b: true } )
|
85
109
|
end
|
86
110
|
|
87
111
|
end
|
@@ -223,6 +223,64 @@ describe Woyo::Attributes do
|
|
223
223
|
|
224
224
|
end
|
225
225
|
|
226
|
+
context 'listeners' do
|
227
|
+
|
228
|
+
let(:lat) { AttrTest.new }
|
229
|
+
let(:listener_class) do
|
230
|
+
class AttrListenerTest
|
231
|
+
attr_reader :changed_attribute, :changed_value
|
232
|
+
def notify attr,value
|
233
|
+
@changed_attribute = attr
|
234
|
+
@changed_value = value
|
235
|
+
end
|
236
|
+
end
|
237
|
+
AttrListenerTest
|
238
|
+
end
|
239
|
+
|
240
|
+
before :each do
|
241
|
+
lat.attribute say: "Hello"
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'are notified of attribute changes' do
|
245
|
+
expect(lat.say).to eq "Hello"
|
246
|
+
listener = listener_class.new
|
247
|
+
lat.attributes.add_listener :say, listener
|
248
|
+
lat.say "Bye"
|
249
|
+
expect(listener.changed_attribute).to eq :say
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'are not notified if value does not change' do
|
253
|
+
expect(lat.say).to eq "Hello"
|
254
|
+
listener = listener_class.new
|
255
|
+
lat.attributes.add_listener :say, listener
|
256
|
+
lat.say "Hello"
|
257
|
+
expect(listener.changed_attribute).to be_nil
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'are notified with attribute and value' do
|
261
|
+
expect(lat.say).to eq "Hello"
|
262
|
+
listener = listener_class.new
|
263
|
+
lat.attributes.add_listener :say, listener
|
264
|
+
lat.say "Bye"
|
265
|
+
expect(listener.changed_attribute).to eq :say
|
266
|
+
expect(listener.changed_value).to eq "Bye"
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'may be multiple' do
|
270
|
+
expect(lat.say).to eq "Hello"
|
271
|
+
listener1 = listener_class.new
|
272
|
+
lat.attributes.add_listener :say, listener1
|
273
|
+
listener2 = listener_class.new
|
274
|
+
lat.attributes.add_listener :say, listener2
|
275
|
+
lat.say "Bye"
|
276
|
+
expect(listener1.changed_attribute).to eq :say
|
277
|
+
expect(listener1.changed_value).to eq "Bye"
|
278
|
+
expect(listener2.changed_attribute).to eq :say
|
279
|
+
expect(listener2.changed_value).to eq "Bye"
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
283
|
+
|
226
284
|
context 'that are boolean have convenient instance accessors' do
|
227
285
|
|
228
286
|
let(:bat) { class BooleanAttrTest; include Woyo::Attributes; end.new }
|
@@ -420,5 +478,52 @@ describe Woyo::Attributes do
|
|
420
478
|
|
421
479
|
end
|
422
480
|
|
481
|
+
context 'changes' do
|
482
|
+
|
483
|
+
let(:cat) { AttrTest.new }
|
484
|
+
|
485
|
+
before :each do
|
486
|
+
cat.attributes :one, :two, :three
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'can be tracked' do
|
490
|
+
expect(cat.changes).to eq nil
|
491
|
+
cat.track_changes
|
492
|
+
expect(cat.changes).to be_instance_of Woyo::Attributes::ChangesHash
|
493
|
+
expect(cat.changes).to be_empty
|
494
|
+
cat.one = 1
|
495
|
+
cat.two = 2
|
496
|
+
expect(cat.changes.count).to eq 2
|
497
|
+
expect(cat.changes[:one]).to eq 1
|
498
|
+
expect(cat.changes[:two]).to eq 2
|
499
|
+
end
|
500
|
+
|
501
|
+
it 'tracking can be cleared' do
|
502
|
+
cat.track_changes
|
503
|
+
cat.three = 3
|
504
|
+
expect(cat.changes[:three]).to eq 3
|
505
|
+
cat.clear_changes
|
506
|
+
expect(cat.changes).to be_empty
|
507
|
+
cat.one = 1
|
508
|
+
expect(cat.changes[:one]).to eq 1
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'tracking includes dependent attributes (hashes with attribute keys)' do
|
512
|
+
cat.attributes :reaction, :hot, :warm, :cool, :cold
|
513
|
+
cat.hot = true
|
514
|
+
cat.reaction hot: 'Sweat', warm: 'Relax', cool: 'Huddle', cold: 'Shiver'
|
515
|
+
cat.track_changes
|
516
|
+
cat.cold = true
|
517
|
+
cat.hot = false
|
518
|
+
changes = cat.changes
|
519
|
+
expect(changes.keys).to include :reaction
|
520
|
+
expect(changes[:reaction]).to eq "Shiver"
|
521
|
+
expect(changes[:cold]).to eq true
|
522
|
+
expect(changes[:hot]).to eq false
|
523
|
+
expect(changes.count).to eq 3
|
524
|
+
end
|
525
|
+
|
526
|
+
end
|
527
|
+
|
423
528
|
end
|
424
529
|
|
@@ -31,12 +31,13 @@ describe Woyo::Attributes::AttributesHash do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'registers attribute listeners' do
|
34
|
-
@attributes.
|
34
|
+
@attributes.add_listener :test, @listener
|
35
35
|
end
|
36
36
|
|
37
|
-
it 'maintains
|
37
|
+
it 'maintains lists of attribute listeners' do
|
38
38
|
expect(@attributes.listeners).to be_kind_of Hash
|
39
|
-
expect(@attributes.listeners[:test]).to
|
39
|
+
expect(@attributes.listeners[:test]).to be_kind_of Array
|
40
|
+
expect(@attributes.listeners[:test].first).to be @listener
|
40
41
|
end
|
41
42
|
|
42
43
|
it 'notifies listeners of attribute change' do
|
@@ -52,7 +53,7 @@ describe Woyo::Attributes::AttributesHash do
|
|
52
53
|
it 'does not notify listener if attribute does not change' do
|
53
54
|
@attributes[:test] = :same_value
|
54
55
|
@listener = Listener.new
|
55
|
-
@attributes.
|
56
|
+
@attributes.add_listener :test, @listener
|
56
57
|
expect(@listener.notified).to be false
|
57
58
|
@attributes[:test] = :same_value
|
58
59
|
expect(@listener.notified).to be false
|
@@ -96,6 +97,11 @@ describe Woyo::Attributes::Group do
|
|
96
97
|
expect(@group.values).to eq %w( dumb bald smart )
|
97
98
|
end
|
98
99
|
|
100
|
+
it 'change tracking includes group as dependent'# do
|
101
|
+
# # simliar method as attributes with hash for value
|
102
|
+
# pending
|
103
|
+
# end
|
104
|
+
|
99
105
|
end
|
100
106
|
|
101
107
|
describe Woyo::Attributes::Exclusion do
|
@@ -116,7 +122,7 @@ describe Woyo::Attributes::Exclusion do
|
|
116
122
|
|
117
123
|
it 'registers as listener for attributes' do
|
118
124
|
@group.members.each do |member|
|
119
|
-
expect(@group.attributes.listeners[member]).to be @group
|
125
|
+
expect(@group.attributes.listeners[member].first).to be @group
|
120
126
|
end
|
121
127
|
end
|
122
128
|
|
@@ -160,4 +166,9 @@ describe Woyo::Attributes::Exclusion do
|
|
160
166
|
expect(@group.value).to eq :cold
|
161
167
|
end
|
162
168
|
|
169
|
+
it 'change tracking includes group and other changed members as dependent'# do
|
170
|
+
# # simliar method as attributes with hash for value
|
171
|
+
# pending
|
172
|
+
# end
|
173
|
+
|
163
174
|
end
|
@@ -82,15 +82,66 @@ describe Woyo::Location do
|
|
82
82
|
|
83
83
|
end
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
85
|
+
context 'actions' do
|
86
|
+
|
87
|
+
it 'execute returns changes for location' do
|
88
|
+
home = Woyo::Location.new :home do
|
89
|
+
item :thing do
|
90
|
+
action :make_changes do
|
91
|
+
execution do |action|
|
92
|
+
name 'Changed item'
|
93
|
+
action.name 'Changed action'
|
94
|
+
location.name 'Changed location'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
expect(home.item(:thing).action(:make_changes).execute[:changes]).to eq( {
|
100
|
+
name: "Changed location",
|
101
|
+
item: {
|
102
|
+
thing: {
|
103
|
+
name: "Changed item",
|
104
|
+
action: {
|
105
|
+
make_changes: {
|
106
|
+
name: "Changed action"
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
})
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'execute returns changes for location for this execution only' do
|
115
|
+
home = Woyo::Location.new :home do
|
116
|
+
item :thing do
|
117
|
+
action :make_changes do
|
118
|
+
attribute count: 0
|
119
|
+
execution do |action|
|
120
|
+
action.count += 1
|
121
|
+
name "Changed item #{action.count}"
|
122
|
+
action.name "Changed action #{action.count}"
|
123
|
+
location.name "Changed location #{action.count}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
action :more_changes do
|
127
|
+
execution do |action|
|
128
|
+
name "Changed item more"
|
129
|
+
action.name "Changed action more"
|
130
|
+
location.name "Changed location more"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
expect(home.item(:thing).action(:make_changes).execute[:changes]).to eq( {
|
136
|
+
name: "Changed location 1", item: { thing: { name: "Changed item 1", action: { make_changes: { count: 1, name: "Changed action 1" } } } }
|
137
|
+
})
|
138
|
+
expect(home.item(:thing).action(:make_changes).execute[:changes]).to eq( {
|
139
|
+
name: "Changed location 2", item: { thing: { name: "Changed item 2", action: { make_changes: { count: 2, name: "Changed action 2" } } } }
|
140
|
+
})
|
141
|
+
expect(home.item(:thing).action(:more_changes).execute[:changes]).to eq( {
|
142
|
+
name: "Changed location more", item: { thing: { name: "Changed item more", action: { more_changes: { name: "Changed action more" } } } }
|
143
|
+
})
|
144
|
+
end
|
145
|
+
end
|
95
146
|
|
96
147
|
end
|
data/spec/woyo/world/way_spec.rb
CHANGED
@@ -160,12 +160,12 @@ describe Woyo::Way do
|
|
160
160
|
end
|
161
161
|
|
162
162
|
it 'when open' do
|
163
|
-
expect(@door.go).to eq ( { go: true,
|
163
|
+
expect(@door.action(:go).execute).to eq ( { describe: 'Swings open', result: { go: true, location: :someplace }, changes: {} } )
|
164
164
|
end
|
165
165
|
|
166
166
|
it 'when closed' do
|
167
167
|
@door.close!
|
168
|
-
expect(@door.go).to eq ( { go: false,
|
168
|
+
expect(@door.action(:go).execute).to eq ( { describe: 'Slams shut', result: { go: false, location: nil }, changes: {} } )
|
169
169
|
end
|
170
170
|
|
171
171
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'woyo/world/world_object'
|
3
|
+
require 'woyo/world/action'
|
3
4
|
|
4
5
|
describe Woyo::WorldObject do
|
5
6
|
|
@@ -43,9 +44,49 @@ describe Woyo::WorldObject do
|
|
43
44
|
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
context '#context' do
|
48
|
+
|
49
|
+
it 'returns parent' do
|
50
|
+
class Thing < Woyo::WorldObject ; children :thing ; end
|
51
|
+
thing1 = Thing.new :thing1 do
|
52
|
+
thing :thing2 do
|
53
|
+
thing :thing3
|
54
|
+
end
|
55
|
+
end
|
56
|
+
thing2 = thing1.thing :thing2
|
57
|
+
thing3 = thing2.thing :thing3
|
58
|
+
expect(thing1.context).to eq nil
|
59
|
+
expect(thing2.context).to eq thing1
|
60
|
+
expect(thing3.context).to eq thing2
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
context "#uid" do
|
66
|
+
|
67
|
+
it 'is object path' do
|
68
|
+
class Thing < Woyo::WorldObject ; children :thing ; end
|
69
|
+
thing1 = Thing.new :thing1 do
|
70
|
+
thing :thing2 do
|
71
|
+
thing :thing3
|
72
|
+
end
|
73
|
+
end
|
74
|
+
thing2 = thing1.thing :thing2
|
75
|
+
thing3 = thing2.thing :thing3
|
76
|
+
expect(thing1.uid).to eq 'thing1'
|
77
|
+
expect(thing2.uid).to eq 'thing1-thing2'
|
78
|
+
expect(thing3.uid).to eq 'thing1-thing2-thing3'
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'lists children' do
|
84
|
+
class Thing < Woyo::WorldObject ; end
|
85
|
+
class Container < Woyo::WorldObject ; children :thing ; end
|
86
|
+
box = Container.new :box do
|
87
|
+
thing :ball
|
88
|
+
end
|
89
|
+
expect(box.children).to eq({ thing: { ball: box.thing(:ball) } })
|
49
90
|
end
|
50
91
|
|
51
92
|
context 'has' do
|
@@ -91,5 +132,63 @@ describe Woyo::WorldObject do
|
|
91
132
|
|
92
133
|
end
|
93
134
|
|
135
|
+
context 'attribute changes' do
|
136
|
+
|
137
|
+
it 'listed for self' do
|
138
|
+
wo = Woyo::WorldObject.new( :thing )
|
139
|
+
expect(wo.changes).to be_empty
|
140
|
+
wo.name = 'Other'
|
141
|
+
expect(wo.changes[:name]).to eq 'Other'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'list includes dependent changes' do
|
145
|
+
wo = Woyo::WorldObject.new( :thing )
|
146
|
+
wo.exclusion :color, :red, :blue
|
147
|
+
wo.description red: 'Red thing', blue: 'Blue thing'
|
148
|
+
wo.changes.clear
|
149
|
+
expect(wo.changes).to be_empty
|
150
|
+
wo.blue = true
|
151
|
+
expect(wo.changes.names).to include :blue
|
152
|
+
expect(wo.changes.names).to include :description
|
153
|
+
expect(wo.changes[:description]).to eq 'Blue thing'
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'list recursively includes changes for children' do
|
157
|
+
class Low < Woyo::WorldObject ; end
|
158
|
+
class Mid < Woyo::WorldObject ; children :low ; end
|
159
|
+
class Top < Woyo::WorldObject ; children :mid ; end
|
160
|
+
t1 = Top.new :t1 do
|
161
|
+
mid(:m1) { low :l1 ; low :l2 ; low :l3 }
|
162
|
+
mid(:m2) { low :l1 ; low :l2 ; low :l3 }
|
163
|
+
mid(:m3) { low :l1 ; low :l2 ; low :l3 }
|
164
|
+
mid(:m4) do
|
165
|
+
low :l1
|
166
|
+
low :l2 do
|
167
|
+
exclusion :make_change, :no, :yes
|
168
|
+
name no: 'Unchanged l2', yes: 'Changed l2'
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
t1.name = 'Changed t1'
|
173
|
+
m1 = t1.mid(:m1)
|
174
|
+
m2 = t1.mid(:m2)
|
175
|
+
m4 = t1.mid(:m4)
|
176
|
+
m1.name = 'Changed m1'
|
177
|
+
m1.low(:l1).name = "Changed l1"
|
178
|
+
m1.low(:l2).name = "Changed l2"
|
179
|
+
m2.low(:l2).name = "Changed l2"
|
180
|
+
m4.low(:l2).yes = true
|
181
|
+
expect(t1.changes).to eq ({
|
182
|
+
name: 'Changed t1',
|
183
|
+
mid: {
|
184
|
+
m1: { name: 'Changed m1', low: { l1: { name: 'Changed l1' }, l2: { name: 'Changed l2' } } },
|
185
|
+
m2: { low: { l2: { name: 'Changed l2' } } },
|
186
|
+
m4: { low: { l2: { name: 'Changed l2', yes: true } } }
|
187
|
+
}
|
188
|
+
})
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
94
193
|
end
|
95
194
|
|
@@ -22,5 +22,15 @@ describe Woyo::World do
|
|
22
22
|
expect(world.items).to be_empty
|
23
23
|
end
|
24
24
|
|
25
|
+
it 'has no context' do
|
26
|
+
expect(world.context).to be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has optional id' do
|
30
|
+
expect(world.id).to be_nil
|
31
|
+
my_world = Woyo::World.new :my_id
|
32
|
+
expect(my_world.id).to eq :my_id
|
33
|
+
end
|
34
|
+
|
25
35
|
end
|
26
36
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: woyo-world
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerard Fowley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|