toystore 0.9.0 → 0.10.0

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.
@@ -0,0 +1,103 @@
1
+ require 'helper'
2
+
3
+ describe Toy::AssociationSerialization do
4
+ uses_constants('User', 'Game', 'Move')
5
+
6
+ before do
7
+ User.attribute :name, String
8
+ User.attribute :age, Integer
9
+ end
10
+
11
+ describe "serializing relationships" do
12
+ before do
13
+ User.list :games, :inverse_of => :user
14
+ Game.reference :user
15
+ end
16
+
17
+ it "should include references" do
18
+ user = User.create(:name => 'John', :age => 28)
19
+ game = user.games.create
20
+
21
+ MultiJson.load(game.to_json(:include => [:user])).should == {
22
+ 'game' => {
23
+ 'id' => game.id,
24
+ 'user_id' => user.id,
25
+ 'user' => {
26
+ 'name' => 'John',
27
+ 'game_ids' => [game.id],
28
+ 'id' => user.id,
29
+ 'age' => 28,
30
+ }
31
+ }
32
+ }
33
+ end
34
+
35
+ it "should include lists" do
36
+ user = User.create(:name => 'John', :age => 28)
37
+ game = user.games.create
38
+ MultiJson.load(user.to_json(:include => [:games])).should == {
39
+ 'user' => {
40
+ 'name' => 'John',
41
+ 'game_ids' => [game.id],
42
+ 'id' => user.id,
43
+ 'age' => 28,
44
+ 'games' => [{'id' => game.id, 'user_id' => user.id}],
45
+ }
46
+ }
47
+ end
48
+
49
+ it "should not cause circular reference JSON errors for references" do
50
+ user = User.create(:name => 'John', :age => 28)
51
+ game = user.games.create
52
+
53
+ MultiJson.load(ActiveSupport::JSON.encode(game.user)).should == {
54
+ 'user' => {
55
+ 'name' => 'John',
56
+ 'game_ids' => [game.id],
57
+ 'id' => user.id,
58
+ 'age' => 28
59
+ }
60
+ }
61
+ end
62
+
63
+ it "should not cause circular reference JSON errors for references when called indirectly" do
64
+ user = User.create(:name => 'John', :age => 28)
65
+ game = user.games.create
66
+
67
+ MultiJson.load(ActiveSupport::JSON.encode([game.user])).should == [
68
+ 'user' => {
69
+ 'name' => 'John',
70
+ 'game_ids' => [game.id],
71
+ 'id' => user.id,
72
+ 'age' => 28
73
+ }
74
+ ]
75
+ end
76
+
77
+ it "should not cause circular reference JSON errors for lists" do
78
+ user = User.create(:name => 'John', :age => 28)
79
+ game = user.games.create
80
+
81
+ MultiJson.load(ActiveSupport::JSON.encode(user.games)).should == [{
82
+ 'game' => {
83
+ 'id' => game.id,
84
+ 'user_id' => user.id
85
+ }
86
+ }]
87
+ end
88
+
89
+ it "should not cause circular reference JSON errors for lists when called indirectly" do
90
+ user = User.create(:name => 'John', :age => 28)
91
+ game = user.games.create
92
+
93
+ MultiJson.load(ActiveSupport::JSON.encode({:games => user.games})).should == {
94
+ 'games' => [{
95
+ 'game' => {
96
+ 'id' => game.id,
97
+ 'user_id' => user.id
98
+ }
99
+ }]
100
+ }
101
+ end
102
+ end
103
+ end
@@ -72,6 +72,22 @@ describe Toy::Attribute do
72
72
  Toy::Attribute.new(User, :age, String, :default => 1).default.should == 1
73
73
  end
74
74
 
75
+ it "allows defaulting to nil" do
76
+ Toy::Attribute.new(User, :age, String, :default => nil).default.should be_nil
77
+ end
78
+
79
+ it "works with callable default" do
80
+ default = lambda { 'foo' }
81
+ attribute = Toy::Attribute.new(User, :age, String, :default => default)
82
+ attribute.default.should == 'foo'
83
+ end
84
+
85
+ it "passes model to callable default" do
86
+ default = lambda { |model| model.name.downcase }
87
+ attribute = Toy::Attribute.new(User, :age, String, :default => default)
88
+ attribute.default.should == 'user'
89
+ end
90
+
75
91
  it "returns store_default if set for type" do
76
92
  Toy::Attribute.new(User, :skills, Array).default.should == []
77
93
  end
@@ -173,4 +189,4 @@ describe Toy::Attribute do
173
189
  Toy::Attribute.new(User, :twitter_access_token, String).abbr?.should be_false
174
190
  end
175
191
  end
176
- end
192
+ end
@@ -17,7 +17,7 @@ describe Toy::Equality do
17
17
  end
18
18
  end
19
19
 
20
- describe "equal?" do
20
+ describe "#equal?" do
21
21
  it "returns true if same object" do
22
22
  user = User.new(:id => 1)
23
23
  user.should equal(user)
@@ -29,4 +29,11 @@ describe Toy::Equality do
29
29
  user.should_not equal(other_user)
30
30
  end
31
31
  end
32
- end
32
+
33
+ describe "#hash" do
34
+ it "returns the hash of the id" do
35
+ user = User.new
36
+ user.hash.should eq(user.id.hash)
37
+ end
38
+ end
39
+ end
@@ -4,7 +4,7 @@ describe "Array.to_store" do
4
4
  it "should convert value to_a" do
5
5
  Array.to_store([1, 2, 3, 4]).should == [1, 2, 3, 4]
6
6
  Array.to_store('1').should == ['1']
7
- Array.to_store({'1' => '2', '3' => '4'}).should == [['1', '2'], ['3', '4']]
7
+ Array.to_store({'1' => '2'}).should == [['1', '2']]
8
8
  end
9
9
  end
10
10
 
@@ -22,4 +22,4 @@ describe "Array.store_default" do
22
22
  it "returns emtpy array" do
23
23
  Array.store_default.should == []
24
24
  end
25
- end
25
+ end
@@ -4,11 +4,43 @@ describe Toy::Identity::UUIDKeyFactory do
4
4
  uses_constants('User')
5
5
 
6
6
  it "should use String as key_type" do
7
- Toy::Identity::UUIDKeyFactory.new.key_type.should be(String)
7
+ subject.key_type.should be(String)
8
8
  end
9
9
 
10
10
  it "should use uuid for next_key" do
11
- Toy::Identity::UUIDKeyFactory.new.next_key(nil).length.should == 36
11
+ subject.next_key(nil).length.should == 36
12
+ end
13
+
14
+ describe "#eql?" do
15
+ it "returns true for same class and key type" do
16
+ subject.eql?(Toy::Identity::UUIDKeyFactory.new).should be_true
17
+ end
18
+
19
+ it "returns false for same class and different key type" do
20
+ other = Toy::Identity::UUIDKeyFactory.new
21
+ other.stub(:key_type).and_return(Integer)
22
+ subject.eql?(other).should be_false
23
+ end
24
+
25
+ it "returns false for different classes" do
26
+ subject.eql?(Object.new).should be_false
27
+ end
28
+ end
29
+
30
+ describe "#==" do
31
+ it "returns true for same class and key type" do
32
+ subject.==(Toy::Identity::UUIDKeyFactory.new).should be_true
33
+ end
34
+
35
+ it "returns false for same class and different key type" do
36
+ other = Toy::Identity::UUIDKeyFactory.new
37
+ other.stub(:key_type).and_return(Integer)
38
+ subject.==(other).should be_false
39
+ end
40
+
41
+ it "returns false for different classes" do
42
+ subject.==(Object.new).should be_false
43
+ end
12
44
  end
13
45
 
14
46
  describe "Declaring key to be uuid" do
@@ -24,4 +56,4 @@ describe Toy::Identity::UUIDKeyFactory do
24
56
  User.attributes['id'].type.should be(String)
25
57
  end
26
58
  end
27
- end
59
+ end
@@ -58,6 +58,10 @@ describe Toy::IdentityMap do
58
58
  user.adapter.should_not_receive(:read)
59
59
  User.get(user.id).should equal(user)
60
60
  end
61
+
62
+ it "returns nil if not found in map or adapter" do
63
+ User.get(1).should be_nil
64
+ end
61
65
  end
62
66
 
63
67
  describe "#reload" do
@@ -0,0 +1,93 @@
1
+ require 'helper'
2
+
3
+ describe 'Toy Inheritance' do
4
+ describe 'using Toy::Object' do
5
+ before do
6
+ class ::Parent
7
+ include Toy::Object
8
+
9
+ attribute :name, String
10
+ end
11
+
12
+ class ::Child < Parent; end
13
+ end
14
+
15
+ after do
16
+ Object.send :remove_const, 'Parent' if defined?(::Parent)
17
+ Object.send :remove_const, 'Child' if defined?(::Child)
18
+ end
19
+
20
+ it "duplicates attributes" do
21
+ Parent.attributes.each do |name, attribute|
22
+ Child.attributes.key?(name).should be_true
23
+ Child.attributes[name].should eq(Parent.attributes[name])
24
+ end
25
+ end
26
+
27
+ it "does not add attributes to the parent" do
28
+ Child.attribute(:foo, String)
29
+ Parent.attributes.keys.should_not include(:foo)
30
+ end
31
+
32
+ it "adds type attribute" do
33
+ Child.attribute?(:type).should be_true
34
+ end
35
+
36
+ it "sets type to class name" do
37
+ Child.new.type.should eq('Child')
38
+ end
39
+
40
+ it "sets the key factory to same as parent" do
41
+ Child.key_factory.should eq(Parent.key_factory)
42
+ end
43
+ end
44
+
45
+ describe 'using Toy::Store' do
46
+ before do
47
+ class ::Degree
48
+ include Toy::Store
49
+ end
50
+
51
+ class ::Parent
52
+ include Toy::Store
53
+
54
+ attribute :name, String
55
+ list :degrees, Degree
56
+ reference :degree, Degree
57
+ end
58
+
59
+ class ::Child < Parent
60
+ list :odd_degrees, Degree
61
+ reference :odd_degree, Degree
62
+ end
63
+ end
64
+
65
+ after do
66
+ Object.send :remove_const, 'Parent' if defined?(::Parent)
67
+ Object.send :remove_const, 'Child' if defined?(::Child)
68
+ Object.send :remove_const, 'Degree' if defined?(::Degree)
69
+ end
70
+
71
+ it "duplicates lists" do
72
+ Child.lists.keys.should include(:degrees)
73
+ Child.lists.keys.should include(:odd_degrees)
74
+ end
75
+
76
+ it "does not add lists to parent" do
77
+ Parent.lists.keys.should_not include(:odd_degrees)
78
+ end
79
+
80
+ it "duplicates references" do
81
+ Child.references.keys.should include(:degree)
82
+ Child.references.keys.should include(:odd_degree)
83
+ end
84
+
85
+ it "does not add references to parent" do
86
+ Parent.references.keys.should_not include(:odd_degree)
87
+ end
88
+
89
+ it "sets the adapter to the same as the parent" do
90
+ Child.adapter.should eq(Parent.adapter)
91
+ end
92
+ end
93
+ end
@@ -8,8 +8,16 @@ describe Toy::Attributes do
8
8
  User.attribute(:age, Integer)
9
9
  end
10
10
 
11
- it "prints out object id and attributes sorted with values" do
12
- user = User.new(:age => 28, :name => 'John')
13
- user.inspect.should == %Q(#<User:#{user.object_id} age: 28, id: "#{user.id}", name: "John">)
11
+ describe ".inspect" do
12
+ it "prints out attribute names and types" do
13
+ User.inspect.should == %Q(User(id:String age:Integer name:String))
14
+ end
14
15
  end
15
- end
16
+
17
+ describe "#inspect" do
18
+ it "prints out object id and attributes sorted with values" do
19
+ user = User.new(:age => 28, :name => 'John')
20
+ user.inspect.should == %Q(#<User:#{user.object_id} id: "#{user.id}", age: 28, name: "John">)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+
3
+ describe Toy::Object do
4
+ uses_objects('User')
5
+
6
+ it "adds model naming" do
7
+ model_name = User.model_name
8
+ model_name.should == 'User'
9
+ model_name.singular.should == 'user'
10
+ model_name.plural.should == 'users'
11
+ end
12
+
13
+ it "adds to_model" do
14
+ user = User.new
15
+ user.to_model.should == user
16
+ end
17
+
18
+ describe "#persisted?" do
19
+ it "returns false" do
20
+ User.new.persisted?.should be_false
21
+ end
22
+ end
23
+
24
+ describe "#to_key" do
25
+ it "returns [id] if persisted" do
26
+ user = User.new
27
+ user.stub(:persisted?).and_return(true)
28
+ user.to_key.should == [user.id]
29
+ end
30
+
31
+ it "returns nil if not persisted" do
32
+ User.new.to_key.should be_nil
33
+ end
34
+ end
35
+
36
+ describe "#to_param" do
37
+ it "returns key joined by - if to_key present" do
38
+ user = User.new
39
+ user.stub(:persisted?).and_return(true)
40
+ user.to_param.should == user.to_key.join('-')
41
+ end
42
+
43
+ it "returns nil if to_key nil" do
44
+ User.new.to_param.should be_nil
45
+ end
46
+ end
47
+ end
@@ -31,9 +31,9 @@ describe Toy::Plugins do
31
31
  end
32
32
 
33
33
  it "adds plugins to classes declared after plugin was called" do
34
- create_constant('Move')
35
- Move.foo.should == 'foo'
36
- Move.new.bar.should == 'bar'
34
+ klass = Class.new { include Toy::Store }
35
+ klass.foo.should == 'foo'
36
+ klass.new.bar.should == 'bar'
37
37
  end
38
38
  end
39
- end
39
+ end
@@ -1,7 +1,7 @@
1
1
  require 'helper'
2
2
 
3
3
  describe Toy::Querying do
4
- uses_constants('User', 'Game')
4
+ uses_constants 'User', 'Game'
5
5
 
6
6
  before do
7
7
  User.attribute :name, String
@@ -87,20 +87,80 @@ describe Toy::Querying do
87
87
  end
88
88
  end
89
89
 
90
- describe ".load (with hash)" do
91
- before { @doc = User.load('1', :name => 'John') }
92
- let(:doc) { @doc }
90
+ describe ".load" do
91
+ before do
92
+ class Admin < ::User; end
93
+ end
94
+
95
+ after do
96
+ Object.send :remove_const, 'Admin' if defined?(Admin)
97
+ end
98
+
99
+ context "without type, hash attrs" do
100
+ before do
101
+ @doc = User.load('1', :name => 'John')
102
+ end
103
+
104
+ it "returns instance" do
105
+ @doc.should be_instance_of(User)
106
+ end
107
+
108
+ it "marks object as persisted" do
109
+ @doc.should be_persisted
110
+ end
111
+
112
+ it "decodes the object" do
113
+ @doc.name.should == 'John'
114
+ end
115
+ end
93
116
 
94
- it "returns instance" do
95
- doc.should be_instance_of(User)
117
+ context "without type, nil attrs" do
118
+ before do
119
+ @doc = User.load('1', nil)
120
+ end
121
+
122
+ it "returns instance" do
123
+ @doc.should be_instance_of(User)
124
+ end
125
+
126
+ it "marks object as persisted" do
127
+ @doc.should be_persisted
128
+ end
129
+
130
+ it "decodes the object" do
131
+ @doc.name.should be_nil
132
+ end
133
+ end
134
+
135
+ context "with symbol type" do
136
+ before do
137
+ @doc = User.load('1', :type => 'Admin', :name => 'John')
138
+ end
139
+
140
+ it "returns instance of type" do
141
+ @doc.should be_instance_of(Admin)
142
+ end
96
143
  end
97
144
 
98
- it "marks object as persisted" do
99
- doc.should be_persisted
145
+ context "with string type" do
146
+ before do
147
+ @doc = User.load('1', 'type' => 'Admin', :name => 'John')
148
+ end
149
+
150
+ it "returns instance of type" do
151
+ @doc.should be_instance_of(Admin)
152
+ end
100
153
  end
101
154
 
102
- it "decodes the object" do
103
- doc.name.should == 'John'
155
+ context "for type that doesn't exist" do
156
+ before do
157
+ Object.send :remove_const, 'Admin' if defined?(::Admin)
158
+ @doc = User.load('1', 'type' => 'Admin', :name => 'John')
159
+ end
160
+
161
+ it "returns instance of loading class" do
162
+ @doc.should be_instance_of(User)
163
+ end
104
164
  end
105
165
  end
106
- end
166
+ end