woyo-world 0.0.1.pre2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Woyo
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'woyo'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install woyo
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/woyo/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,41 @@
1
+
2
+ module Woyo
3
+
4
+ module Attributes
5
+
6
+ module ClassMethods
7
+
8
+ def attributes *attrs
9
+ @attributes ||= [] # class instance variable in ClassMethods scope
10
+ return @attributes if attrs.empty?
11
+ @attributes = attrs # todo: allow additions to existing attributes
12
+ @attributes.each do |attr|
13
+ class_eval("
14
+ def #{attr}= arg
15
+ attributes[:#{attr}] = @#{attr} = arg
16
+ end
17
+ def #{attr}(arg=nil)
18
+ if arg.nil?
19
+ @#{attr}
20
+ else
21
+ self.#{attr} = arg
22
+ end
23
+ end
24
+ ")
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ def self.included(base)
31
+ base.extend(ClassMethods)
32
+ end
33
+
34
+ def attributes
35
+ @attributes ||= {}
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
@@ -0,0 +1,32 @@
1
+ require_relative 'world_object'
2
+
3
+ module Woyo
4
+
5
+ class Character < WorldObject
6
+
7
+ attributes :name, :description
8
+
9
+ def world
10
+ @world ||= context if context.is_a? World
11
+ end
12
+
13
+ def location
14
+ @location ||= context if context.is_a? Location
15
+ end
16
+
17
+ def me
18
+ self
19
+ end
20
+
21
+ def go way_or_id
22
+ id = way_or_id.kind_of?(Way) ? way_or_id.id : way_or_id
23
+ way = @location.ways[id]
24
+ @location.characters.delete me.id
25
+ @location = way.to
26
+ @location.characters[me.id] = me
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,59 @@
1
+
2
+ module Woyo
3
+
4
+ module DSL
5
+
6
+ def evaluate &block
7
+ (block.arity < 1 ? (instance_eval &block) : block.call(self)) if block_given?
8
+ self
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ def contains *conts
14
+ @contains ||= [] # class instance variable in ClassMethods scope
15
+ return @contains if conts.empty?
16
+ conts.each { |cont| @contains << cont unless @contains.include? cont }
17
+ @contains.each do |cont|
18
+ class_eval("
19
+
20
+ def #{cont}s
21
+ ( @contains ||= {} )[:#{cont}] ||= ( @#{cont}s ||= {} )
22
+ end
23
+
24
+ def #{cont} cont_or_id, &block
25
+ #{cont} = cont_or_id.kind_of?( #{cont.capitalize} ) ? cont_or_id : nil
26
+ id = #{cont} ? #{cont}.id : cont_or_id
27
+ known = self.#{cont}s[id] ? true : false
28
+ case
29
+ when #{cont} && known && block_given? then #{cont}.evaluate &block
30
+ when #{cont} && known && !block_given? then #{cont}
31
+ when #{cont} && !known && block_given? then self.#{cont}s[id] = #{cont}.evaluate &block
32
+ when #{cont} && !known && !block_given? then self.#{cont}s[id] = #{cont}
33
+ when !#{cont} && known && block_given? then #{cont} = self.#{cont}s[id].evaluate &block
34
+ when !#{cont} && known && !block_given? then #{cont} = self.#{cont}s[id]
35
+ when !#{cont} && !known && block_given? then #{cont} = self.#{cont}s[id] = #{cont.capitalize}.new id, context: self, &block
36
+ when !#{cont} && !known && !block_given? then #{cont} = self.#{cont}s[id] = #{cont.capitalize}.new id, context: self
37
+ end
38
+ # maybe: god-like lists of everything at world level... would need unique ids... self.world.#{cont}s[id] = #{cont} if !known && self.world
39
+ #{cont}
40
+ end
41
+
42
+ ")
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ def self.included(base)
49
+ base.extend(ClassMethods)
50
+ end
51
+
52
+ def contains
53
+ @contains ||= {}
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
@@ -0,0 +1,22 @@
1
+ require_relative 'world_object'
2
+
3
+ module Woyo
4
+
5
+ class Location < WorldObject
6
+
7
+ attributes :name, :description
8
+
9
+ contains :way, :character
10
+
11
+ def world
12
+ self.context
13
+ end
14
+
15
+ def here
16
+ self
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
@@ -0,0 +1,3 @@
1
+ module Woyo
2
+ WORLD_VERSION = "0.0.1.pre2"
3
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'world_object'
2
+
3
+ module Woyo
4
+
5
+ class Way < WorldObject
6
+
7
+ attributes :name, :description
8
+
9
+ def from
10
+ @from ||= context
11
+ end
12
+
13
+ def world
14
+ from ? from.world : nil
15
+ end
16
+
17
+ def to= arg
18
+ if arg.instance_of? Symbol
19
+ case
20
+ when from && arg == from.id
21
+ @to = from # way loops back to the same location
22
+ when world && world.locations[arg]
23
+ @to = world.locations[arg] # destination location already exists in world
24
+ when world
25
+ @to = world.location arg # create destination location in world
26
+ else
27
+ @to = Location.new arg # create free-standing destination location
28
+ end
29
+ end
30
+ end
31
+
32
+ def to arg=nil
33
+ if arg.nil?
34
+ @to
35
+ else
36
+ self.to = arg
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,18 @@
1
+ require_relative 'world_object'
2
+ require_relative 'location'
3
+ require_relative 'way'
4
+ require_relative 'character'
5
+
6
+ module Woyo
7
+
8
+ class World < WorldObject
9
+
10
+ contains :location, :character
11
+
12
+ def initialize &block
13
+ super nil, context: nil, &block
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,24 @@
1
+
2
+ require_relative 'attributes'
3
+ require_relative 'dsl'
4
+
5
+ module Woyo
6
+
7
+ class WorldObject
8
+
9
+ include Attributes
10
+ include DSL
11
+
12
+ attr_reader :id, :context
13
+ attr_accessor :_test
14
+
15
+ def initialize id, context: nil, &block
16
+ @id = id.to_s.downcase.to_sym
17
+ @context = context
18
+ evaluate &block
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
data/lib/woyo/world.rb ADDED
@@ -0,0 +1,3 @@
1
+ require_relative 'world/version'
2
+ require_relative 'world/world'
3
+
@@ -0,0 +1,62 @@
1
+ require 'woyo/world/attributes'
2
+
3
+ describe Woyo::Attributes do
4
+
5
+ before :all do
6
+ class AttrTest
7
+ include Woyo::Attributes
8
+ attributes :attr1, :attr2, :attr3
9
+ end
10
+ end
11
+
12
+ it 'names can be listed for class' do
13
+ attrs = AttrTest.attributes
14
+ attrs.should be_instance_of Array
15
+ attrs.count.should eq 3
16
+ attrs.all? { |a| a.is_a? Symbol }.should be_true
17
+ end
18
+
19
+ it 'names and values can be retrieved for instance' do
20
+ attrs = AttrTest.new.attributes
21
+ attrs.should be_instance_of Hash
22
+ end
23
+
24
+ it 'can be written with =' do
25
+ attr_test = AttrTest.new
26
+ AttrTest.attributes.each do |attr|
27
+ eval "attr_test.#{attr} = '#{attr}'.upcase"
28
+ end
29
+ attr_test.attributes.count.should eq AttrTest.attributes.count
30
+ attr_test.attributes.each do |name,value|
31
+ value.should eq name.to_s.upcase
32
+ end
33
+ end
34
+
35
+ it 'can be written without =' do
36
+ attr_test = AttrTest.new
37
+ AttrTest.attributes.each do |attr|
38
+ eval "attr_test.#{attr} '#{attr}'.upcase"
39
+ end
40
+ attr_test.attributes.count.should eq AttrTest.attributes.count
41
+ attr_test.attributes.each do |name,value|
42
+ value.should eq name.to_s.upcase
43
+ end
44
+ end
45
+
46
+ it 'can be read' do
47
+ attr_test = AttrTest.new
48
+ AttrTest.attributes.each do |attr|
49
+ eval "attr_test.#{attr} '#{attr}'.upcase"
50
+ end
51
+ attr_test.attributes.count.should eq AttrTest.attributes.count
52
+ attr_test.attributes.each do |name,value|
53
+ eval("attr_test.#{name}").should eq value
54
+ end
55
+ end
56
+
57
+ it 'accepts string or symbol key for retrieval'
58
+
59
+ it 'accepts string of symbol key for assignment'
60
+
61
+ end
62
+
@@ -0,0 +1,42 @@
1
+ require 'woyo/world/character'
2
+ require 'woyo/world/world'
3
+ require 'woyo/world/location'
4
+
5
+ describe Woyo::Character do
6
+
7
+ it 'accepts world for parameter context:' do
8
+ wo = nil
9
+ expect { wo = Woyo::Character.new(:my_id, context: Woyo::World.new) }.to_not raise_error
10
+ wo.context.should be_instance_of Woyo::World
11
+ end
12
+
13
+ it 'accepts location for parameter context:' do
14
+ wo = nil
15
+ expect { wo = Woyo::Character.new(:my_id, context: Woyo::Location.new(:here)) }.to_not raise_error
16
+ wo.context.should be_instance_of Woyo::Location
17
+ wo.context.id.should eq :here
18
+ end
19
+
20
+ it 'can go way' do
21
+ world = Woyo::World.new do
22
+ location :home do
23
+ way :out do
24
+ to :away
25
+ end
26
+ character :tom
27
+ end
28
+ location :away do
29
+ end
30
+ end
31
+ home = world.locations[:home]
32
+ away = world.locations[:away]
33
+ tom = home.characters[:tom]
34
+ tom.location.should be home
35
+ tom.go :out
36
+ tom.location.should be away
37
+ home.characters[:tom].should be_nil
38
+ away.characters[:tom].should eq tom
39
+ end
40
+
41
+ end
42
+
@@ -0,0 +1,79 @@
1
+ require 'woyo/world/dsl'
2
+
3
+ describe Woyo::DSL do
4
+
5
+ before :all do
6
+ class DSLTest
7
+ include Woyo::DSL
8
+ contains :dog, :cat
9
+ end
10
+ class Dog ; def initialize id, context: nil ; end ; end
11
+ class Cat ; def initialize id, context: nil ; end ; end
12
+ end
13
+
14
+ context '#evaluate' do
15
+
16
+ it 'instance evals block with arity 0' do
17
+ dsl = DSLTest.new
18
+ result = dsl.evaluate { self.should == dsl }
19
+ result.should be dsl
20
+ end
21
+
22
+ it 'passes self to block with arity 1' do
23
+ dsl = DSLTest.new
24
+ result = dsl.evaluate { |scope| scope.should be dsl }
25
+ result.should be dsl
26
+ end
27
+
28
+ end
29
+
30
+ it 'can list classes to contain' do
31
+ DSLTest.contains.should eq [ :dog, :cat ]
32
+ end
33
+
34
+ it 'can add classes to contain' do
35
+ pending 'fix containment'
36
+ class DSLTestMore < DSLTest
37
+ contains :cow
38
+ contains :duck
39
+ end
40
+ # class Cow ; def initialize id, context: nil ; end ; end
41
+ # class Duck ; def initialize id, context: nil ; end ; end
42
+ DSLTestMore.contains.should eq [ :dog, :cat, :cow, :duck ]
43
+ end
44
+
45
+ it 'can create contained objects' do
46
+ dsl = DSLTest.new
47
+ dog = dsl.dog :brown
48
+ dog.should be_instance_of Dog
49
+ dsl.dog(:brown).should be dog
50
+ dsl.dogs[:brown].should be dog
51
+ end
52
+
53
+ it 'can list each contained object by class' do
54
+ dsl = DSLTest.new
55
+ dog_brown = dsl.dog :brown
56
+ dog_black = dsl.dog :black
57
+ cat_white = dsl.cat :white
58
+ cat_black = dsl.cat :black
59
+ dsl.dogs.should eq Hash[ brown: dog_brown, black: dog_black ]
60
+ dsl.cats.should eq Hash[ white: cat_white, black: cat_black ]
61
+ end
62
+
63
+ it 'can list all contained objects' do
64
+ dsl = DSLTest.new
65
+ dog_brown = dsl.dog :brown
66
+ dog_black = dsl.dog :black
67
+ cat_white = dsl.cat :white
68
+ cat_black = dsl.cat :black
69
+ dsl.contains.keys.should eq [ :dog, :cat ]
70
+ cats = Hash[ white: cat_white, black: cat_black ]
71
+ dogs = Hash[ brown: dog_brown, black: dog_black ]
72
+ dsl.contains.should eq Hash[ dog: dogs, cat: cats ]
73
+ end
74
+
75
+ it 'accepts string or symbol key for contained object retrieval'
76
+
77
+ it 'accepts string of symbol key for contained object assignment'
78
+
79
+ end