woyo-world 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/woyo/world/actions.rb +24 -0
- data/lib/woyo/world/attributes.rb +105 -154
- data/lib/woyo/world/character.rb +4 -1
- data/lib/woyo/world/{dsl.rb → evaluate.rb} +1 -2
- data/lib/woyo/world/group.rb +21 -6
- data/lib/woyo/world/item.rb +26 -0
- data/lib/woyo/world/location.rb +5 -3
- data/lib/woyo/world/version.rb +1 -1
- data/lib/woyo/world/way.rb +5 -4
- data/lib/woyo/world/world.rb +7 -3
- data/lib/woyo/world/world_object.rb +8 -4
- data/rspec.json +1 -0
- data/spec/spec_doc.haml +68 -0
- data/spec/spec_doc_formatter.rb +89 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/woyo/dsl/dsl_spec.rb +367 -0
- data/spec/woyo/world/actions_spec.rb +71 -0
- data/spec/woyo/world/attributes_spec.rb +300 -382
- data/spec/woyo/world/character_spec.rb +30 -28
- data/spec/woyo/world/evaluate_spec.rb +75 -0
- data/spec/woyo/world/group_spec.rb +45 -44
- data/spec/woyo/world/item_spec.rb +46 -0
- data/spec/woyo/world/location_spec.rb +48 -32
- data/spec/woyo/world/way_spec.rb +54 -45
- data/spec/woyo/world/world_object_spec.rb +48 -6
- data/spec/woyo/world/world_spec.rb +15 -7
- data/todo.txt +2 -2
- data/woyo-world.gemspec +3 -2
- metadata +38 -11
- data/spec/woyo/world/dsl_spec.rb +0 -74
- data/spec/woyo/world/language_spec.rb +0 -350
data/lib/woyo/world/version.rb
CHANGED
data/lib/woyo/world/way.rb
CHANGED
@@ -4,9 +4,11 @@ module Woyo
|
|
4
4
|
|
5
5
|
class Way < WorldObject
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
def initialize_object
|
8
|
+
super
|
9
|
+
attribute :going
|
10
|
+
exclusion :passable, :closed, :open # defaults to closed: true
|
11
|
+
end
|
10
12
|
|
11
13
|
def world
|
12
14
|
from ? from.world : nil
|
@@ -46,7 +48,6 @@ class Way < WorldObject
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
attribute :going
|
50
51
|
|
51
52
|
def go
|
52
53
|
{ go: open?, going: self.going }
|
data/lib/woyo/world/world.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
require_relative 'world_object'
|
2
2
|
require_relative 'location'
|
3
3
|
require_relative 'way'
|
4
|
+
require_relative 'item'
|
4
5
|
require_relative 'character'
|
5
6
|
|
6
7
|
module Woyo
|
7
8
|
|
8
9
|
class World < WorldObject
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
children :location, :character, :item
|
12
|
+
|
13
|
+
def initialize_object
|
14
|
+
super
|
15
|
+
attributes :start
|
16
|
+
end
|
13
17
|
|
14
18
|
def initialize &block
|
15
19
|
super nil, context: nil, &block
|
@@ -1,14 +1,15 @@
|
|
1
1
|
|
2
2
|
require_relative 'attributes'
|
3
|
-
require_relative '
|
3
|
+
require_relative 'actions'
|
4
|
+
require_relative 'evaluate'
|
4
5
|
|
5
6
|
module Woyo
|
6
7
|
|
7
8
|
class WorldObject
|
8
9
|
|
9
|
-
#prepend Attributes
|
10
10
|
include Attributes
|
11
|
-
include
|
11
|
+
include Actions
|
12
|
+
include Evaluate
|
12
13
|
|
13
14
|
attr_reader :id, :context
|
14
15
|
attr_accessor :_test
|
@@ -16,10 +17,13 @@ class WorldObject
|
|
16
17
|
def initialize id, context: nil, &block
|
17
18
|
@id = id.to_s.downcase.to_sym
|
18
19
|
@context = context
|
19
|
-
|
20
|
+
attributes :description, name: proc { id.to_s.capitalize }
|
21
|
+
initialize_object
|
20
22
|
evaluate &block
|
21
23
|
end
|
22
24
|
|
25
|
+
def initialize_object ; end
|
26
|
+
|
23
27
|
end
|
24
28
|
|
25
29
|
end
|
data/rspec.json
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"examples":[{"description":"#attributes returns empty AttributesHash for instance with no attributes","full_description":"Woyo::Attributes #attributes returns empty AttributesHash for instance with no attributes","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":12,"run_time":0.000600822},{"description":"#attributes returns AttributesHash with names and nil values for instance with unpopulated attributes","full_description":"Woyo::Attributes #attributes returns AttributesHash with names and nil values for instance with unpopulated attributes","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":18,"run_time":0.000109135},{"description":"#attributes returns AttributeHash with names and values for instance with populated attributes","full_description":"Woyo::Attributes #attributes returns AttributeHash with names and values for instance with populated attributes","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":26,"run_time":9.0917e-05},{"description":"#attributes returns AttributesHash with names and default values for instance with unpopulated attributes","full_description":"Woyo::Attributes #attributes returns AttributesHash with names and default values for instance with unpopulated attributes","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":37,"run_time":0.000109444},{"description":"have convenience accessor :names for :keys","full_description":"Woyo::Attributes have convenience accessor :names for :keys","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":45,"run_time":6.8282e-05},{"description":"can be written via method with =","full_description":"Woyo::Attributes can be written via method with =","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":51,"run_time":8.5617e-05},{"description":"can be written via method without =","full_description":"Woyo::Attributes can be written via method without =","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":62,"run_time":9.4259e-05},{"description":"can be read via method","full_description":"Woyo::Attributes can be read via method","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":73,"run_time":0.00011345},{"description":"list can be added to","full_description":"Woyo::Attributes list can be added to","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":84,"run_time":0.000106628},{"description":"list can be added to without duplication","full_description":"Woyo::Attributes list can be added to without duplication","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":92,"run_time":0.000101618},{"description":"can be defined with \"attribute\"","full_description":"Woyo::Attributes can be defined with \"attribute\"","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":100,"run_time":0.001249877},{"description":"can have a default value","full_description":"Woyo::Attributes can have a default value","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":108,"run_time":0.000179756},{"description":"can have a default proc","full_description":"Woyo::Attributes can have a default proc","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":122,"run_time":7.4385e-05},{"description":"default proc runs in instance scope","full_description":"Woyo::Attributes default proc runs in instance scope","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":128,"run_time":6.1819e-05},{"description":"can have a default lambda","full_description":"Woyo::Attributes can have a default lambda","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":135,"run_time":7.0772e-05},{"description":"default lambda runs in instance scope","full_description":"Woyo::Attributes default lambda runs in instance scope","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":141,"run_time":6.8076e-05},{"description":"#attr?","full_description":"Woyo::Attributes that are boolean have convenient instance accessors #attr?","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":156,"run_time":0.000111265},{"description":"#attr!","full_description":"Woyo::Attributes that are boolean have convenient instance accessors #attr!","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":161,"run_time":8.0153e-05},{"description":"#is? :attr","full_description":"Woyo::Attributes that are boolean have convenient instance accessors #is? :attr","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":168,"run_time":8.5972e-05},{"description":"#is :attr","full_description":"Woyo::Attributes that are boolean have convenient instance accessors #is :attr","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":174,"run_time":7.2978e-05},{"description":"without duplication","full_description":"Woyo::Attributes can be re-defined without duplication","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":187,"run_time":7.9704e-05},{"description":"to set default","full_description":"Woyo::Attributes can be re-defined to set default","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":195,"run_time":7.7479e-05},{"description":"to change default","full_description":"Woyo::Attributes can be re-defined to change default","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":203,"run_time":7.7911e-05},{"description":"can be accessed by named instance methods","full_description":"Woyo::Attributes groups can be accessed by named instance methods","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":221,"run_time":9.9924e-05},{"description":"names and nil values can be retrieved","full_description":"Woyo::Attributes groups names and nil values can be retrieved","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":225,"run_time":0.000104594},{"description":"names and default values can be retrieved","full_description":"Woyo::Attributes groups names and default values can be retrieved","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":232,"run_time":0.000131944},{"description":"members can be accessed via group","full_description":"Woyo::Attributes groups members can be accessed via group","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":240,"run_time":8.8867e-05},{"description":"members are attributes","full_description":"Woyo::Attributes groups members are attributes","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":246,"run_time":7.9698e-05},{"description":"attributes are members","full_description":"Woyo::Attributes groups attributes are members","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":252,"run_time":8.2007e-05},{"description":"#groups returns hash with names and groups","full_description":"Woyo::Attributes groups #groups returns hash with names and groups","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":257,"run_time":0.000117097},{"description":"can be accessed by named instance methods","full_description":"Woyo::Attributes exclusions can be accessed by named instance methods","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":272,"run_time":0.000133484},{"description":"first member is true, rest are false","full_description":"Woyo::Attributes exclusions first member is true, rest are false","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":276,"run_time":0.000113933},{"description":"#value returns true member","full_description":"Woyo::Attributes exclusions #value returns true member","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":282,"run_time":0.000118077},{"description":"making group member true affects member attributes","full_description":"Woyo::Attributes exclusions making group member true affects member attributes","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":288,"run_time":0.000109708},{"description":"making attribute true affects group members","full_description":"Woyo::Attributes exclusions making attribute true affects group members","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":295,"run_time":0.000111194},{"description":"#exclusions returns hash with names and exlcusions","full_description":"Woyo::Attributes exclusions #exclusions returns hash with names and exlcusions","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":302,"run_time":0.000174007},{"description":"accept a hash as value","full_description":"Woyo::Attributes with Hash value accept a hash as value","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":317,"run_time":0.000699821},{"description":"return the value of the first key that evaluates as a true attribute","full_description":"Woyo::Attributes with Hash value return the value of the first key that evaluates as a true attribute","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":321,"run_time":0.000107057},{"description":"otherwise return the hash","full_description":"Woyo::Attributes with Hash value otherwise return the hash","status":"passed","file_path":"./spec/woyo/world/attributes_spec.rb","line_number":329,"run_time":8.6088e-05},{"description":"has attributes","full_description":"Woyo::Character has attributes","status":"passed","file_path":"./spec/woyo/world/character_spec.rb","line_number":10,"run_time":0.000106901},{"description":"name attribute defaults to id","full_description":"Woyo::Character name attribute defaults to id","status":"passed","file_path":"./spec/woyo/world/character_spec.rb","line_number":15,"run_time":7.87e-05},{"description":"accepts world for parameter context:","full_description":"Woyo::Character accepts world for parameter context:","status":"passed","file_path":"./spec/woyo/world/character_spec.rb","line_number":19,"run_time":0.000115722},{"description":"accepts location for parameter context:","full_description":"Woyo::Character accepts location for parameter context:","status":"passed","file_path":"./spec/woyo/world/character_spec.rb","line_number":25,"run_time":0.000113242},{"description":"has attributes","full_description":"DSL world has attributes","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":10,"run_time":0.000108365},{"description":"contains locations","full_description":"DSL world contains locations","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":21,"run_time":0.000181966},{"description":"defined with attributes","full_description":"DSL location defined with attributes","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":60,"run_time":0.000128587},{"description":"redefined","full_description":"DSL location redefined","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":73,"run_time":0.000141228},{"description":"multiple with attributes","full_description":"DSL location multiple with attributes","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":96,"run_time":0.000179429},{"description":"to new location","full_description":"DSL ways new way to new location","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":125,"run_time":0.000273266},{"description":"to existing location","full_description":"DSL ways new way to existing location","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":146,"run_time":0.000254083},{"description":"to same location","full_description":"DSL ways new way to same location","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":169,"run_time":0.000205929},{"description":"to new location","full_description":"DSL ways existing way to new location","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":192,"run_time":0.000304538},{"description":"to existing location","full_description":"DSL ways existing way to existing location","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":217,"run_time":0.000259085},{"description":"to same location","full_description":"DSL ways existing way to same location","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":244,"run_time":0.001997442},{"description":"an open way","full_description":"DSL ways going an open way","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":288,"run_time":0.000162764},{"description":"a closed way","full_description":"DSL ways going a closed way","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":297,"run_time":0.00016135},{"description":"new","full_description":"DSL ways character new","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":344,"run_time":0.000153027},{"description":"existing","full_description":"DSL ways character existing","status":"passed","file_path":"./spec/woyo/world/dsl_spec.rb","line_number":359,"run_time":0.000133853},{"description":"can list classes to contain","full_description":"Woyo::Evaluate can list classes to contain","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":31,"run_time":7.1558e-05},{"description":"can add classes to contain","full_description":"Woyo::Evaluate can add classes to contain","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":35,"run_time":0.000917174},{"description":"can create child objects","full_description":"Woyo::Evaluate can create child objects","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":45,"run_time":6.8278e-05},{"description":"has hashes of each class of child objects","full_description":"Woyo::Evaluate has hashes of each class of child objects","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":53,"run_time":6.8478e-05},{"description":"hash a hash of all classes of child objects","full_description":"Woyo::Evaluate hash a hash of all classes of child objects","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":63,"run_time":6.7888e-05},{"description":"instance evals block with arity 0","full_description":"Woyo::Evaluate#evaluate instance evals block with arity 0","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":17,"run_time":0.00149878},{"description":"passes self to block with arity 1","full_description":"Woyo::Evaluate#evaluate passes self to block with arity 1","status":"passed","file_path":"./spec/woyo/world/evaluate_spec.rb","line_number":23,"run_time":5.4524e-05},{"description":"is a kind of hash","full_description":"Woyo::Attributes::AttributesHash is a kind of hash","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":22,"run_time":0.00022712},{"description":"provides list of attribute names","full_description":"Woyo::Attributes::AttributesHash provides list of attribute names","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":29,"run_time":4.5909e-05},{"description":"registers attribute listeners","full_description":"Woyo::Attributes::AttributesHash registers attribute listeners","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":33,"run_time":3.4579e-05},{"description":"maintains list of attribute listeners","full_description":"Woyo::Attributes::AttributesHash maintains list of attribute listeners","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":37,"run_time":4.5437e-05},{"description":"notifies listeners of attribute change","full_description":"Woyo::Attributes::AttributesHash notifies listeners of attribute change","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":42,"run_time":5.7731e-05},{"description":"does not notify listener if attribute does not change","full_description":"Woyo::Attributes::AttributesHash does not notify listener if attribute does not change","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":52,"run_time":5.6067e-05},{"description":"#initialize requires attributes object","full_description":"Woyo::Attributes::Group #initialize requires attributes object","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":70,"run_time":0.000125452},{"description":"maintains list of members","full_description":"Woyo::Attributes::Group maintains list of members","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":75,"run_time":5.1099e-05},{"description":"member names can be listed","full_description":"Woyo::Attributes::Group member names can be listed","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":79,"run_time":3.8831e-05},{"description":"members are backed by attributes","full_description":"Woyo::Attributes::Group members are backed by attributes","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":83,"run_time":5.7155e-05},{"description":"member values can be listed","full_description":"Woyo::Attributes::Group member values can be listed","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":95,"run_time":4.9062e-05},{"description":"has default","full_description":"Woyo::Attributes::Exclusion has default","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":107,"run_time":4.4003e-05},{"description":"defaults to first member true, the rest false","full_description":"Woyo::Attributes::Exclusion defaults to first member true, the rest false","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":111,"run_time":4.4923e-05},{"description":"registers as listener for attributes","full_description":"Woyo::Attributes::Exclusion registers as listener for attributes","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":117,"run_time":4.5312e-05},{"description":"setting a member true changes the rest to false","full_description":"Woyo::Attributes::Exclusion setting a member true changes the rest to false","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":123,"run_time":4.8502e-05},{"description":"for a group > 2 members setting a true member false reverts to default","full_description":"Woyo::Attributes::Exclusion for a group > 2 members setting a true member false reverts to default","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":130,"run_time":5.7171e-05},{"description":"for a binary group setting a true member false sets the other true","full_description":"Woyo::Attributes::Exclusion for a binary group setting a true member false sets the other true","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":137,"run_time":6.3755e-05},{"description":"can only set existing members","full_description":"Woyo::Attributes::Exclusion can only set existing members","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":146,"run_time":5.4135e-05},{"description":"can be reset to default!","full_description":"Woyo::Attributes::Exclusion can be reset to default!","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":150,"run_time":5.147e-05},{"description":"#value returns name of true member","full_description":"Woyo::Attributes::Exclusion #value returns name of true member","status":"passed","file_path":"./spec/woyo/world/group_spec.rb","line_number":156,"run_time":4.7433e-05},{"description":"has attributes","full_description":"Woyo::Location has attributes","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":10,"run_time":9.6657e-05},{"description":"name attribute defaults to id","full_description":"Woyo::Location name attribute defaults to id","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":15,"run_time":6.7713e-05},{"description":"accepts world for parameter context:","full_description":"Woyo::Location accepts world for parameter context:","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":19,"run_time":0.000110204},{"description":"#here","full_description":"Woyo::Location #here","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":60,"run_time":6.2542e-05},{"description":"#world","full_description":"Woyo::Location #world","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":65,"run_time":8.7446e-05},{"description":"are listed (#ways)","full_description":"Woyo::Location ways are listed (#ways)","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":27,"run_time":0.000370378},{"description":"are from here","full_description":"Woyo::Location ways are from here","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":37,"run_time":0.00018087},{"description":"go to locations","full_description":"Woyo::Location ways go to locations","status":"passed","file_path":"./spec/woyo/world/location_spec.rb","line_number":47,"run_time":0.000181489},{"description":"has attributes","full_description":"Woyo::Way has attributes","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":10,"run_time":0.000131892},{"description":"name attribute defaults to id","full_description":"Woyo::Way name attribute defaults to id","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":15,"run_time":0.000110511},{"description":"accepts location for parameter context:","full_description":"Woyo::Way accepts location for parameter context:","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":19,"run_time":0.000144638},{"description":"is in a world","full_description":"Woyo::Way is in a world","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":26,"run_time":0.000154878},{"description":"leads from a location","full_description":"Woyo::Way leads from a location","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":33,"run_time":0.00013702},{"description":"leads to a location","full_description":"Woyo::Way leads to a location","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":39,"run_time":0.000158177},{"description":"defaults to closed if \"to\" not defined","full_description":"Woyo::Way defaults to closed if \"to\" not defined","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":47,"run_time":0.000118832},{"description":"defaults to open if \"to\" defined","full_description":"Woyo::Way defaults to open if \"to\" defined","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":53,"run_time":0.000142426},{"description":"may be made closed","full_description":"Woyo::Way may be made closed","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":60,"run_time":0.000135807},{"description":"may be made open","full_description":"Woyo::Way may be made open","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":70,"run_time":0.000114594},{"description":"may be closed!","full_description":"Woyo::Way may be closed!","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":79,"run_time":0.000143574},{"description":"can close!","full_description":"Woyo::Way can close!","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":89,"run_time":0.000145269},{"description":"can open!","full_description":"Woyo::Way can open!","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":99,"run_time":0.000141241},{"description":"query open?","full_description":"Woyo::Way query open?","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":108,"run_time":0.000244526},{"description":"query closed?","full_description":"Woyo::Way query closed?","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":116,"run_time":0.00023091},{"description":"can be described","full_description":"Woyo::Way description can be described","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":130,"run_time":6.2399e-05},{"description":"can be described open","full_description":"Woyo::Way description can be described open","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":135,"run_time":4.7681e-05},{"description":"can be described closed","full_description":"Woyo::Way description can be described closed","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":140,"run_time":4.769e-05},{"description":"when open","full_description":"Woyo::Way going when open","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":155,"run_time":6.4966e-05},{"description":"when closed","full_description":"Woyo::Way going when closed","status":"passed","file_path":"./spec/woyo/world/way_spec.rb","line_number":159,"run_time":5.0029e-05},{"description":"provides access to context","full_description":"Woyo::WorldObject provides access to context","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":46,"run_time":4.924e-05},{"description":"initializes with symbol id","full_description":"Woyo::WorldObject#new initializes with symbol id","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":8,"run_time":5.4612e-05},{"description":"creates id","full_description":"Woyo::WorldObject#new creates id","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":12,"run_time":4.2743e-05},{"description":"converts id to lowercase","full_description":"Woyo::WorldObject#new converts id to lowercase","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":16,"run_time":4.7502e-05},{"description":"accepts named parameter context:","full_description":"Woyo::WorldObject#new accepts named parameter context:","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":20,"run_time":5.3458e-05},{"description":"accepts a block with arity 0","full_description":"Woyo::WorldObject#new accepts a block with arity 0","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":24,"run_time":5.6628e-05},{"description":"instance evals block with arity 0","full_description":"Woyo::WorldObject#new instance evals block with arity 0","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":30,"run_time":6.2236e-05},{"description":"accepts a block with arity 1","full_description":"Woyo::WorldObject#new accepts a block with arity 1","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":34,"run_time":4.4374e-05},{"description":"passes self to block with arity 1","full_description":"Woyo::WorldObject#new passes self to block with arity 1","status":"passed","file_path":"./spec/woyo/world/world_object_spec.rb","line_number":40,"run_time":4.3688e-05},{"description":"has attributes :name, :description, :start","full_description":"Woyo::World has attributes :name, :description, :start","status":"passed","file_path":"./spec/woyo/world/world_spec.rb","line_number":8,"run_time":9.4831e-05},{"description":"initializes with no locations","full_description":"Woyo::World initializes with no locations","status":"passed","file_path":"./spec/woyo/world/world_spec.rb","line_number":13,"run_time":0.000129167},{"description":"initializes with no characters","full_description":"Woyo::World initializes with no characters","status":"passed","file_path":"./spec/woyo/world/world_spec.rb","line_number":17,"run_time":0.000126987}],"summary":{"duration":0.023193178,"example_count":125,"failure_count":0,"pending_count":0},"summary_line":"125 examples, 0 failures"}
|
data/spec/spec_doc.haml
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
- def render_specdoc specdoc
|
3
|
+
- specdoc.each do |element|
|
4
|
+
- case
|
5
|
+
- when element.keys.first == :head then render_head element
|
6
|
+
- when element.keys.first == :text then render_text element
|
7
|
+
- when element.keys.first == :group then render_group element
|
8
|
+
- when element.keys.first == :example then render_example element
|
9
|
+
|
10
|
+
- def render_group group_element
|
11
|
+
- group = group_element.values.first
|
12
|
+
- unless group.first[:hide]
|
13
|
+
- haml_tag :div do
|
14
|
+
- group.each do |element|
|
15
|
+
- case
|
16
|
+
- when element.keys.first == :head then render_head element, 2
|
17
|
+
- when element.keys.first == :text then render_text element
|
18
|
+
- when element.keys.first == :group then render_group element
|
19
|
+
- when element.keys.first == :example then render_example element
|
20
|
+
|
21
|
+
- def render_example example_element
|
22
|
+
- example = example_element.values.first
|
23
|
+
- unless example.first[:hide]
|
24
|
+
- haml_tag :div do
|
25
|
+
- example.each do |element|
|
26
|
+
- case
|
27
|
+
- when element.keys.first == :head then render_head element, 3
|
28
|
+
- when element.keys.first == :text then render_text element
|
29
|
+
- when element.keys.include?(:code) then render_code element
|
30
|
+
|
31
|
+
- def render_head head_element, size = 1
|
32
|
+
- case size
|
33
|
+
- when 1 then haml_tag :h1, head_element.values.first
|
34
|
+
- when 2 then haml_tag :h2, head_element.values.first
|
35
|
+
- when 3 then haml_tag :h3, head_element.values.first
|
36
|
+
- when 4 then haml_tag :h4, head_element.values.first
|
37
|
+
- when 5 then haml_tag :h5, head_element.values.first
|
38
|
+
- else haml_tag :h6, head_element.values.first
|
39
|
+
|
40
|
+
- def render_text text_element
|
41
|
+
- haml_tag :p, text_element.values.first
|
42
|
+
|
43
|
+
- def render_code code_element
|
44
|
+
- unless code_element[:hide]
|
45
|
+
- haml_tag :div do
|
46
|
+
- haml_tag :pre, "<code>#{preserve(code_element[:code])}#{' #=> ' + code_element[:value].to_s if code_element[:value]}</code>"
|
47
|
+
|
48
|
+
%html
|
49
|
+
|
50
|
+
%head
|
51
|
+
%meta{ charset: 'utf-8' }
|
52
|
+
%meta{ 'http-equiv' => "X-UA-Compatible", content: "chrome=1" }
|
53
|
+
%meta{ name: "description", content: specdoc.first[:group].collect { |element| element[:title] }.compact.first + ' : ' + specdoc.first[:group].collect { |element| element[:tagline] }.compact.first }
|
54
|
+
%link{ rel: "stylesheet", type: "text/css", media: "screen", href: "stylesheets/stylesheet.css" }
|
55
|
+
%title= specdoc.first[:group].collect { |element| element[:title] }.compact.first
|
56
|
+
|
57
|
+
%body
|
58
|
+
|
59
|
+
%div#header_wrap.outer
|
60
|
+
%header.inner
|
61
|
+
%a#forkme_banner{ href: specdoc.first[:group].collect { |element| element[:url] }.compact.first } View on GitHub
|
62
|
+
%h1#project_title= specdoc.first[:group].collect { |element| element[:title] }.compact.first
|
63
|
+
%h2#project_tagline= specdoc.first[:group].collect { |element| element[:tagline] }.compact.first
|
64
|
+
|
65
|
+
%div#main_content_wrap.outer
|
66
|
+
%section#main_content.inner
|
67
|
+
- render_specdoc specdoc
|
68
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
RSpec::Support.require_rspec_core "formatters/base_formatter"
|
2
|
+
RSpec::Support.require_rspec_core "formatters/console_codes"
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'haml'
|
6
|
+
|
7
|
+
class SpecDocFormatter < RSpec::Core::Formatters::BaseFormatter
|
8
|
+
|
9
|
+
RSpec::Core::Formatters.register self,
|
10
|
+
:start,
|
11
|
+
:example_group_started, :example_group_finished,
|
12
|
+
:example_passed, :example_failed, :example_pending,
|
13
|
+
:stop
|
14
|
+
|
15
|
+
def initialize(output)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def start(start_notification)
|
20
|
+
@specdoc_root = []
|
21
|
+
@specdoc_group = @specdoc_root
|
22
|
+
@specdoc_parents = []
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop(examples_notification)
|
26
|
+
# if option[:json]
|
27
|
+
#output.puts json_format
|
28
|
+
# end
|
29
|
+
# if option[:haml]
|
30
|
+
output.puts haml_format
|
31
|
+
# end
|
32
|
+
end
|
33
|
+
|
34
|
+
def json_format
|
35
|
+
JSON.pretty_generate @specdoc_root
|
36
|
+
end
|
37
|
+
|
38
|
+
def haml_format
|
39
|
+
Haml::Engine.new( File.read( File.join File.dirname( __FILE__ ), 'spec_doc.haml' )).render( self, specdoc: @specdoc_root )
|
40
|
+
end
|
41
|
+
|
42
|
+
def example_group_started(group_notification)
|
43
|
+
this_group = group_notification.group
|
44
|
+
this_group.init_specdoc
|
45
|
+
this_group_specdoc = this_group.metadata[:specdoc][this_group]
|
46
|
+
@specdoc_group << { group: this_group_specdoc }
|
47
|
+
@specdoc_parents << @specdoc_group
|
48
|
+
@specdoc_group = this_group_specdoc
|
49
|
+
@specdoc_group << { description: this_group.description }
|
50
|
+
end
|
51
|
+
|
52
|
+
def example_group_finished(group_notification)
|
53
|
+
@specdoc_group = @specdoc_parents.pop
|
54
|
+
end
|
55
|
+
|
56
|
+
def example_passed(example_notification)
|
57
|
+
collect_example example_notification, :passed
|
58
|
+
end
|
59
|
+
|
60
|
+
def example_pending(example_notification)
|
61
|
+
collect_example example_notification, :pending
|
62
|
+
end
|
63
|
+
|
64
|
+
def example_failed(example_notification)
|
65
|
+
collect_example example_notification, :failed
|
66
|
+
end
|
67
|
+
|
68
|
+
def collect_example example_notification, result
|
69
|
+
this_example = example_notification.example
|
70
|
+
this_specdoc = this_example.metadata[:specdoc]
|
71
|
+
unless this_specdoc.any? { |element| element[:head] }
|
72
|
+
description = this_example.description
|
73
|
+
this_specdoc.unshift({ head: description == description.upcase ? description : description.capitalize })
|
74
|
+
end
|
75
|
+
this_specdoc.unshift( { result: result } )
|
76
|
+
placeholder = @specdoc_group.detect { |element| element[:example] == false }
|
77
|
+
if placeholder
|
78
|
+
placeholder[:example] = this_specdoc
|
79
|
+
else
|
80
|
+
@specdoc_group << { example: this_specdoc }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def indent
|
85
|
+
':' * @specdoc_parents.count
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.expect_with :rspec do |c|
|
3
|
+
c.syntax = [:should, :expect]
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
|
9
|
+
config.around :example do |example|
|
10
|
+
@example = example
|
11
|
+
@example.metadata[:specdoc] = []
|
12
|
+
@binding = @example.example_group_instance.eval_binding
|
13
|
+
|
14
|
+
def hide
|
15
|
+
@example.metadata[:specdoc] << { hide: true }
|
16
|
+
end
|
17
|
+
|
18
|
+
def head text
|
19
|
+
@example.metadata[:specdoc] << { head: text }
|
20
|
+
end
|
21
|
+
|
22
|
+
def text text
|
23
|
+
@example.metadata[:specdoc] << { text: text }
|
24
|
+
end
|
25
|
+
|
26
|
+
def code code
|
27
|
+
code_hash = case
|
28
|
+
when code.is_a?( String )
|
29
|
+
{ code: code }
|
30
|
+
when code.respond_to?( :[] ) && code[:code]
|
31
|
+
code
|
32
|
+
when [:keys,:values,:count].all? { |m| code.respond_to? m } && code.count == 1
|
33
|
+
{ code: code.keys.first, value: code.values.first }
|
34
|
+
else
|
35
|
+
raise "Don't know what to do with: #{code}"
|
36
|
+
end
|
37
|
+
code_hash[:code] = fix_indent(code_hash[:code])
|
38
|
+
@example.metadata[:specdoc] << code_hash
|
39
|
+
exec_code code_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
def exec_code code
|
43
|
+
if code[:value]
|
44
|
+
expect(@binding.eval code.values_at(:pre,:code,:post).join "\n").to self.send((code[:op] ? code[:op] : :eq),(@binding.eval code[:value]))
|
45
|
+
else
|
46
|
+
@binding.eval code.values_at(:pre,:code,:post).join "\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def fix_indent text
|
51
|
+
lines = text.lines
|
52
|
+
leading = lines.collect { |l| l.index /[^ ]/ }
|
53
|
+
indent = leading.reject { |n| n == 0 }.min
|
54
|
+
if indent
|
55
|
+
indent_regex = Regexp.new('^'+' '*indent)
|
56
|
+
lines.each { |l| l.sub!(indent_regex,'') }
|
57
|
+
end
|
58
|
+
lines.join
|
59
|
+
end
|
60
|
+
|
61
|
+
example.run
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class RSpec::Core::ExampleGroup
|
68
|
+
|
69
|
+
def eval_binding
|
70
|
+
binding
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.title title
|
74
|
+
init_specdoc
|
75
|
+
metadata[:specdoc][self] << { title: title }
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.tagline tagline
|
79
|
+
init_specdoc
|
80
|
+
metadata[:specdoc][self] << { tagline: tagline }
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.url url
|
84
|
+
init_specdoc
|
85
|
+
metadata[:specdoc][self] << { url: url }
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.hide
|
89
|
+
init_specdoc
|
90
|
+
metadata[:specdoc][self] << { hide: true }
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.head head
|
94
|
+
init_specdoc
|
95
|
+
metadata[:specdoc][self] << { head: head }
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.text text
|
99
|
+
init_specdoc
|
100
|
+
metadata[:specdoc][self] << { text: text }
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.init_specdoc
|
104
|
+
metadata[:specdoc] = {} unless metadata[:specdoc]
|
105
|
+
metadata[:specdoc][self] = [] unless metadata[:specdoc][self]
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.doc *args, &block
|
109
|
+
init_specdoc
|
110
|
+
metadata[:specdoc][self] << { example: false } # empty example order placeholder
|
111
|
+
example *args, &block
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
@@ -0,0 +1,367 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'woyo/world/world'
|
3
|
+
|
4
|
+
describe 'DSL' do
|
5
|
+
|
6
|
+
title "Woyo World"
|
7
|
+
tagline "World of Your Own"
|
8
|
+
url "https://github.com/iqeo/woyo-world"
|
9
|
+
|
10
|
+
head "WOYO : World of Your Own"
|
11
|
+
text "This gem woyo-world is a Ruby-based DSL (Domain Specific Language) for creating and interacting with a virtual world. A world is comprised of locations to visit, and ways to go between locations."
|
12
|
+
|
13
|
+
context 'world' do
|
14
|
+
|
15
|
+
before :all do
|
16
|
+
@world = Woyo::World.new
|
17
|
+
end
|
18
|
+
def world ; @world ; end
|
19
|
+
|
20
|
+
head "World"
|
21
|
+
text "A world is comprised of attributes and objects, including locations, items, characters, etc.."
|
22
|
+
|
23
|
+
doc 'has attributes' do
|
24
|
+
head "Attributes"
|
25
|
+
text "A world has attributes that describe and define it's operation."
|
26
|
+
code pre: "world.evaluate do",
|
27
|
+
code: "name 'Small'
|
28
|
+
description 'A small world.'
|
29
|
+
start :home",
|
30
|
+
post: "end"
|
31
|
+
text "Attributes may be accessed from the world."
|
32
|
+
text "The 'name' attribute is to be presented to the user"
|
33
|
+
code "world.name" => "'Small'"
|
34
|
+
text "The 'description' attrbute is to be presented to the user"
|
35
|
+
code "world.description" => "'A small world.'"
|
36
|
+
text "The 'start' attribute refers to the location the user will start at in the world..."
|
37
|
+
code "world.start" => ":home"
|
38
|
+
text "...in this case 'home'."
|
39
|
+
end
|
40
|
+
|
41
|
+
text "The most interesting worlds contain locations to visit."
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'locations' do
|
46
|
+
|
47
|
+
before :all do
|
48
|
+
@world = Woyo::World.new
|
49
|
+
end
|
50
|
+
def world ; @world ; end
|
51
|
+
|
52
|
+
head "Locations"
|
53
|
+
text "A location is a place to visit in a world."
|
54
|
+
|
55
|
+
doc "from humble beginnings" do
|
56
|
+
text "A single location"
|
57
|
+
code pre: "world.evaluate do",
|
58
|
+
code: "location :home do
|
59
|
+
name 'My Home'
|
60
|
+
description 'This old house.'
|
61
|
+
end",
|
62
|
+
post: "end"
|
63
|
+
text "Locations have an identifier (in this case :home) that is unique within the world."
|
64
|
+
text "A location may be referenced like this..."
|
65
|
+
code "home = world.locations[:home]"
|
66
|
+
text "...or this..."
|
67
|
+
code "home = world.location :home"
|
68
|
+
text "To get information about the location..."
|
69
|
+
code "home.id" => ":home"
|
70
|
+
code "home.name" => "'My Home'"
|
71
|
+
code "home.description" => "'This old house.'"
|
72
|
+
text "This is a nice old house, but let's make some changes to it..."
|
73
|
+
end
|
74
|
+
|
75
|
+
doc "change begins at home" do
|
76
|
+
text "Let's make some changes to this location."
|
77
|
+
code pre: "home = world.location :home
|
78
|
+
world.evaluate do",
|
79
|
+
code: "location :home do
|
80
|
+
description 'Sweet home.'
|
81
|
+
end",
|
82
|
+
post: "end"
|
83
|
+
text "The new description replaces the old one."
|
84
|
+
text "Now our home looks like this..."
|
85
|
+
code "home.name" => "'My Home'"
|
86
|
+
code "home.description" => "'Sweet home.'"
|
87
|
+
text "No matter how sweet, this little world is not very interesting..."
|
88
|
+
code "world.locations.count" => "1"
|
89
|
+
text "Let's expand our horizons..."
|
90
|
+
end
|
91
|
+
|
92
|
+
doc "expandng horizons" do
|
93
|
+
text "Add a location to our world"
|
94
|
+
code pre: "home = world.location :home
|
95
|
+
world.evaluate do",
|
96
|
+
code: "location :garden do
|
97
|
+
name 'Garden'
|
98
|
+
description 'A green leafy place.'
|
99
|
+
end",
|
100
|
+
post: "end"
|
101
|
+
text "Now our world is a little more interesting..."
|
102
|
+
code "world.locations.count" => "2"
|
103
|
+
code "garden = world.location :garden"
|
104
|
+
text "This seems like a nice garden..."
|
105
|
+
code "garden.id" => ":garden"
|
106
|
+
code "garden.name" => "'Garden'"
|
107
|
+
code "garden.description" => "'A green leafy place.'"
|
108
|
+
text "We'd like to visit this garden, but there's no way, really..."
|
109
|
+
code "home.ways" => "{}"
|
110
|
+
code "garden.ways" => "{}"
|
111
|
+
text "To go from location to location we need Ways"
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'ways' do
|
117
|
+
|
118
|
+
before :all do
|
119
|
+
@world = Woyo::World.new
|
120
|
+
end
|
121
|
+
|
122
|
+
def world ; @world ; end
|
123
|
+
|
124
|
+
head "Ways"
|
125
|
+
text "A way is a directional path between locations."
|
126
|
+
|
127
|
+
doc "from here to there" do
|
128
|
+
text "A way is defined within a location."
|
129
|
+
code pre: "world.evaluate do",
|
130
|
+
code: "location :here do
|
131
|
+
way :road do
|
132
|
+
to :there
|
133
|
+
description 'A short road'
|
134
|
+
going 'Takes a long time'
|
135
|
+
end
|
136
|
+
end",
|
137
|
+
post: "end"
|
138
|
+
text "Ways have an identifier (in this case :road) that is unique within that location."
|
139
|
+
text "A way may be referenced like this..."
|
140
|
+
code "here = world.locations[:here]" => nil
|
141
|
+
code "way = here.ways[:road]" => nil
|
142
|
+
text "...or this..."
|
143
|
+
code "here = world.location :here"
|
144
|
+
code "way = here.way :road"
|
145
|
+
text "The way's attributes include a description that may be included in location representation to the user."
|
146
|
+
code "way.description" => "'A short road'"
|
147
|
+
text "The location the way is defined within is the location the way is 'from'."
|
148
|
+
code "way.from.id" => ":here"
|
149
|
+
text "Ways connect 'to' a location (in this case :there). This location is created if it does not already exist."
|
150
|
+
code "way.to.id" => ":there"
|
151
|
+
end
|
152
|
+
|
153
|
+
doc "going a way" do
|
154
|
+
text "Ways connect locations so that a user can move about in your world. Usually upon user input, the user goes a way from location to location. An optional description of the 'going' may be presented."
|
155
|
+
code pre: "world.evaluate do",
|
156
|
+
code: "location :room do
|
157
|
+
way :stairs do
|
158
|
+
to :cellar
|
159
|
+
description 'Rickety stairs lead down into darkness.'
|
160
|
+
going 'Creaky steps lead uncertainly downwards...'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
location :cellar do
|
164
|
+
description 'Dark and damp, as expected.'
|
165
|
+
end",
|
166
|
+
post: "end"
|
167
|
+
text "Accessing the location and way..."
|
168
|
+
code "room = world.location :room" => nil
|
169
|
+
code "stairs = room.way :stairs" => nil
|
170
|
+
text "When we try to 'go' a way, the result describes the attempt."
|
171
|
+
code "attempt = stairs.go" => "{ go: true, going: 'Creaky steps lead uncertainly downwards...' }"
|
172
|
+
text "Whether successful or not (true in this case)..."
|
173
|
+
code "attempt[:go]" => "true"
|
174
|
+
text "And a description of the attempt..."
|
175
|
+
code "attempt[:going]" => "'Creaky steps lead uncertainly downwards...'"
|
176
|
+
end
|
177
|
+
|
178
|
+
doc "on the way" do
|
179
|
+
text "Ways may be open or closed, optionally with descriptions for each state. A user cannot go a closed way, and an alternative 'going' description may be presented if attempted."
|
180
|
+
code pre: "world.evaluate do",
|
181
|
+
code: "location :room do
|
182
|
+
way :stairs do
|
183
|
+
to :cellar
|
184
|
+
description open: 'Rickety stairs lead down into darkness.',
|
185
|
+
closed: 'Broken stairs end in darkness.'
|
186
|
+
going open: 'Creaky steps lead uncertainly downwards...',
|
187
|
+
closed: 'The dangerous stairs are impassable.'
|
188
|
+
end
|
189
|
+
end
|
190
|
+
location :cellar do
|
191
|
+
description 'Dark and damp, as expected.'
|
192
|
+
end",
|
193
|
+
post: "end"
|
194
|
+
text "Accessing the location and way..."
|
195
|
+
code "room = world.location :room" => nil
|
196
|
+
code "stairs = room.way :stairs" => nil
|
197
|
+
text "Ways that go 'to' a location are open by default."
|
198
|
+
code "stairs.open?" => "true"
|
199
|
+
text "With an appropriate description."
|
200
|
+
code "stairs.description" => "'Rickety stairs lead down into darkness.'"
|
201
|
+
text "Going an open way succeeds."
|
202
|
+
code "attempt = stairs.go" => "{ go: true, going: 'Creaky steps lead uncertainly downwards...' }"
|
203
|
+
code "attempt[:go]" => "true"
|
204
|
+
code "attempt[:going]" => "'Creaky steps lead uncertainly downwards...'"
|
205
|
+
text "A way may be closed."
|
206
|
+
code "stairs.close!"
|
207
|
+
code "stairs.closed?" => "true"
|
208
|
+
text "The way has an appropriate description."
|
209
|
+
code "stairs.description" => "'Broken stairs end in darkness.'"
|
210
|
+
text "Going a closed way fails."
|
211
|
+
code "attempt = stairs.go" => "{ go: false, going: 'The dangerous stairs are impassable.' }"
|
212
|
+
code "attempt[:go]" => "false"
|
213
|
+
code "attempt[:going]" => "'The dangerous stairs are impassable.'"
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'items' do
|
219
|
+
|
220
|
+
head 'Items'
|
221
|
+
|
222
|
+
doc 'stuff here' do
|
223
|
+
pending
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'attributes' do
|
229
|
+
|
230
|
+
before :all do
|
231
|
+
@world = Woyo::World.new
|
232
|
+
end
|
233
|
+
def world ; @world ; end
|
234
|
+
|
235
|
+
head "Attributes"
|
236
|
+
|
237
|
+
doc "things change" do
|
238
|
+
text "Attribute values may be dynamic, their value determined by a Ruby code block. The value of the last expression in the block is the value assigned to the attribte."
|
239
|
+
code pre: "world.evaluate do",
|
240
|
+
code: "item :clock do
|
241
|
+
attribute :time do
|
242
|
+
Time.now.to_s
|
243
|
+
end
|
244
|
+
end",
|
245
|
+
post: "end"
|
246
|
+
text "'Time.now.to_s' is a Ruby expression that returns the current time in human readable string. Since it is the last (only) expression in the code block, it's value will be assigned to the attribute ':time'."
|
247
|
+
code "clock = world.item :clock"
|
248
|
+
code "clock.time" => "Time.now.to_s"
|
249
|
+
text "The code block will be evaluated each time the attribute is accessed, returning the current time. Let's wait a second and check the time again."
|
250
|
+
code "sleep 1"
|
251
|
+
code "clock.time" => "Time.now.to_s"
|
252
|
+
end
|
253
|
+
|
254
|
+
doc "these things" do
|
255
|
+
text "A dynamic attribute can access other attributes of the same object."
|
256
|
+
text "A simple calculator."
|
257
|
+
code pre: "world.evaluate do",
|
258
|
+
code: "item :calculator do
|
259
|
+
attribute a: 1, b: 2
|
260
|
+
attribute :sum do
|
261
|
+
a + b
|
262
|
+
end
|
263
|
+
end",
|
264
|
+
post: "end"
|
265
|
+
text "Attribute 'sum' accesses attributes 'a' and 'b' and adds them."
|
266
|
+
code "calculator = world.item :calculator"
|
267
|
+
code "calculator.sum" => "3"
|
268
|
+
text "Being a dynamic attribute, changes to the related attributes affect the result."
|
269
|
+
code "calculator.a = 4"
|
270
|
+
code "calculator.b = 5"
|
271
|
+
code "calculator.sum" => "9"
|
272
|
+
end
|
273
|
+
|
274
|
+
doc "those things" do
|
275
|
+
text "Dynamic attributes provide a mechanism for one object to affect another. The Ruby code block may simply refer to an attribute of another object."
|
276
|
+
code pre: "world.evaluate do",
|
277
|
+
code: "item :bulb do
|
278
|
+
attribute color: 'red'
|
279
|
+
end
|
280
|
+
item :lamp do
|
281
|
+
attribute :light do
|
282
|
+
( world.item :bulb ).color
|
283
|
+
end
|
284
|
+
end",
|
285
|
+
post: "end"
|
286
|
+
text "The lamp's light depends on the bulb color."
|
287
|
+
code "lamp = world.item :lamp"
|
288
|
+
code "lamp.light" => "'red'"
|
289
|
+
text "Let's change the bulb."
|
290
|
+
code "bulb = world.item :bulb"
|
291
|
+
code "bulb.color = 'green'"
|
292
|
+
text "New we see the lamp in a new light."
|
293
|
+
code "lamp.light" => "'green'"
|
294
|
+
end
|
295
|
+
|
296
|
+
text "All things... to access attributes of other objects, see 'Context'."
|
297
|
+
text "Being Ruby code, dynamic attributes could be used to make changes to other world objects, attributes, etc.., even to execute any arbitrary Ruby code. Don't do it, this way lies madness."
|
298
|
+
text "Dynamic attributes are intended only to provide a dynamic value to a attribute, not to change other attributes or world objects. Another mechanism: 'Actions', is intended to modify the world."
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'context' do
|
303
|
+
|
304
|
+
before :all do
|
305
|
+
@world = Woyo::World.new
|
306
|
+
end
|
307
|
+
def world ; @world ; end
|
308
|
+
|
309
|
+
head 'Context'
|
310
|
+
text "Other objects may be referred to in different ways."
|
311
|
+
|
312
|
+
doc 'world' do
|
313
|
+
pending
|
314
|
+
end
|
315
|
+
|
316
|
+
doc 'location' do
|
317
|
+
pending
|
318
|
+
end
|
319
|
+
|
320
|
+
doc 'context' do
|
321
|
+
pending
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
325
|
+
|
326
|
+
context "actions" do
|
327
|
+
|
328
|
+
before :all do
|
329
|
+
@world = Woyo::World.new
|
330
|
+
end
|
331
|
+
def world ; @world ; end
|
332
|
+
|
333
|
+
head "Actions"
|
334
|
+
text "World objects may have actions that can be invoked, usually via user interaction."
|
335
|
+
text "Actions change the state of the world, usually by changing the value of attributes on world objects"
|
336
|
+
|
337
|
+
doc "making changes" do
|
338
|
+
text "Actions may be defined for a world object, in this case, an item."
|
339
|
+
code pre: "world.evaluate do",
|
340
|
+
code: "location :here do
|
341
|
+
item :thing do
|
342
|
+
name 'Thing?'
|
343
|
+
action :one do
|
344
|
+
name 'Thing One'
|
345
|
+
end
|
346
|
+
action :two do
|
347
|
+
name 'Thing Two'
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end",
|
351
|
+
post: "end"
|
352
|
+
text "Initially the name is as defined"
|
353
|
+
code "location = world.location :here"
|
354
|
+
code "thing = location.item :thing" => "world.locations[:here].items[:thing]"
|
355
|
+
code "thing.name" => "'Thing?'"
|
356
|
+
text "Invoking action 'one', changes the name."
|
357
|
+
code "thing.one"
|
358
|
+
code "thing.name" => "'Thing One'"
|
359
|
+
text "Invoking action 'two', changes the name again."
|
360
|
+
code "thing.two"
|
361
|
+
code "thing.name" => "'Thing Two'"
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
|