arunthampi-supermodel 0.1.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.
- data/MIT-LICENSE +20 -0
- data/README +23 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/lib/supermodel.rb +9 -0
- data/lib/supermodel/base.rb +284 -0
- data/lib/supermodel/errors.rb +6 -0
- data/lib/supermodel/support.rb +2 -0
- data/lib/supermodel/support/extensions.rb +80 -0
- data/lib/supermodel/support/inflections.rb +52 -0
- data/lib/supermodel/support/inflector.rb +277 -0
- data/spec/base/from_json_spec.rb +70 -0
- data/spec/base/has_many_spec.rb +89 -0
- data/spec/base/has_one_spec.rb +80 -0
- data/spec/base/has_spec.rb +88 -0
- data/spec/base/initialize_spec.rb +64 -0
- data/spec/base/marshal_dump_spec.rb +64 -0
- data/spec/base/marshal_load_spec.rb +58 -0
- data/spec/base/module_spec.rb +15 -0
- data/spec/base/nested_class_spec.rb +16 -0
- data/spec/base/to_json_spec.rb +73 -0
- data/spec/spec_helper.rb +9 -0
- data/supermodel.gemspec +15 -0
- metadata +83 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "A class which is a subclass of SuperModel::Base with a has_one association" do
|
4
|
+
before(:each) do
|
5
|
+
class PhoneNumber < SuperModel::Base
|
6
|
+
has :mobile_number, :which_is => :text
|
7
|
+
end
|
8
|
+
|
9
|
+
class Contact < SuperModel::Base
|
10
|
+
has_one :phone_number
|
11
|
+
end
|
12
|
+
|
13
|
+
@c = Contact.new
|
14
|
+
@p1 = PhoneNumber.new(:mobile_number => '(666) 666-6666')
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
Object.send(:remove_const, :PhoneNumber)
|
19
|
+
Object.send(:remove_const, :Contact)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have an instance variable called associations which is a Hash with the key being :phone_number" do
|
23
|
+
Contact.has_one_associations.class.should == Hash
|
24
|
+
Contact.has_one_associations.keys.should == [:phone_number]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have methods called phone_number and phone_number=" do
|
28
|
+
@c.should respond_to(:phone_number)
|
29
|
+
@c.should respond_to(:phone_number=)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a method called people which returns an empty array" do
|
33
|
+
@c.phone_number.should == nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be able to set a Person object to the association, and over-ride any previous settings" do
|
37
|
+
@c.phone_number = @p1
|
38
|
+
@c.phone_number.should == @p1
|
39
|
+
|
40
|
+
p2 = PhoneNumber.new
|
41
|
+
|
42
|
+
@c.phone_number = p2
|
43
|
+
@c.phone_number.should == p2
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "An object instantiated from class which is a subclass of SuperModel::Base" do
|
49
|
+
before(:each) do
|
50
|
+
class Pet < SuperModel::Base
|
51
|
+
has :name
|
52
|
+
end
|
53
|
+
|
54
|
+
class Person < SuperModel::Base
|
55
|
+
has :name
|
56
|
+
has_one :pet
|
57
|
+
end
|
58
|
+
|
59
|
+
@pet = Pet.new(:name => "Tom")
|
60
|
+
@person1 = Person.new(:name => 'McLovin', :pet => @pet)
|
61
|
+
@person2 = Person.new(:name => 'Seth', :pet => {:name => 'Jerry'})
|
62
|
+
end
|
63
|
+
|
64
|
+
after(:each) do
|
65
|
+
Object.send(:remove_const, :Person)
|
66
|
+
Object.send(:remove_const, :Pet)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be able to initialize with a hash which contains descendents of SuperModel::Base" do
|
70
|
+
@pet.name.should == "Tom"
|
71
|
+
|
72
|
+
@person1.name.should == 'McLovin'
|
73
|
+
@person1.pet.should == @pet
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should be able to initialize from a hash which contains only Strings" do
|
77
|
+
@person2.name.should == 'Seth'
|
78
|
+
@person2.pet.name.should == 'Jerry'
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "A class which is a subclass of SuperModel::Base" do
|
4
|
+
before(:each) do
|
5
|
+
class Person < SuperModel::Base
|
6
|
+
has :name, :which_is => :text
|
7
|
+
end
|
8
|
+
# Initialize a new Person object
|
9
|
+
@p = Person.new
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:each) do
|
13
|
+
Object.send(:remove_const, :Person)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a method called name which returns the value of the variable name" do
|
17
|
+
@p.should respond_to(:name)
|
18
|
+
@p.name.should == ""
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a method called name= which should let you set the instance variable name" do
|
22
|
+
@p.should respond_to(:name=)
|
23
|
+
@p.name = "McLovin"
|
24
|
+
@p.name.should == "McLovin"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "A class which is a subclass of SuperModel::Base with a default value specified" do
|
29
|
+
before(:each) do
|
30
|
+
class NamedPerson < SuperModel::Base
|
31
|
+
has :name, :which_is => :text, :with_default_value => "McLovin"
|
32
|
+
end
|
33
|
+
|
34
|
+
@n = NamedPerson.new
|
35
|
+
end
|
36
|
+
|
37
|
+
after(:each) do
|
38
|
+
Object.send(:remove_const, :NamedPerson)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have a method called name which returns the value of the variable name" do
|
42
|
+
@n.should respond_to(:name)
|
43
|
+
@n.name.should == "McLovin"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have a method called name= which should let you set the instance variable name" do
|
47
|
+
@n.should respond_to(:name=)
|
48
|
+
@n.name = "Seth"
|
49
|
+
@n.name.should == "Seth"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "A class which is a subclass of SuperModel::Base with a default numerical value specified" do
|
54
|
+
before(:each) do
|
55
|
+
class AgedPerson < SuperModel::Base
|
56
|
+
has :name
|
57
|
+
has :age, :which_is => :number, :with_default_value => 10
|
58
|
+
end
|
59
|
+
|
60
|
+
@a = AgedPerson.new
|
61
|
+
end
|
62
|
+
|
63
|
+
after(:each) do
|
64
|
+
Object.send(:remove_const, :AgedPerson)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have an instance variable called attributes which is a Hash with the keys being :name, :age" do
|
68
|
+
AgedPerson.attributes.class.should == Hash
|
69
|
+
AgedPerson.attributes.keys.index(:name).should_not == nil
|
70
|
+
AgedPerson.attributes.keys.index(:age).should_not == nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have methods called name and age which return the values of the variables name and age respectively" do
|
74
|
+
@a.should respond_to(:name)
|
75
|
+
@a.should respond_to(:age)
|
76
|
+
|
77
|
+
@a.name.should == ""
|
78
|
+
@a.age.should == 10
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have a method called name= which should let you set the instance variable name" do
|
82
|
+
@a.should respond_to(:name=)
|
83
|
+
@a.should respond_to(:age=)
|
84
|
+
|
85
|
+
@a.age = 15
|
86
|
+
@a.age.should == 15
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "SuperModel::Base #new method with a hash containing one key-value pair" do
|
4
|
+
before(:all) do
|
5
|
+
class Person < SuperModel::Base
|
6
|
+
has :name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:all) do
|
11
|
+
Object.send(:remove_const, :Person)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be able to initialize attributes correctly from a hash" do
|
15
|
+
p = Person.new(:name => 'McLovin')
|
16
|
+
p.name.should == 'McLovin'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "SuperModel::Base #new method with a hash containing more than one key-value pair" do
|
21
|
+
before(:all) do
|
22
|
+
class Person < SuperModel::Base
|
23
|
+
has :name
|
24
|
+
has :age, :which_is => :number, :with_default_value => 25
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
after(:all) do
|
29
|
+
Object.send(:remove_const, :Person)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be able to initialize attributes correctly from the hash" do
|
33
|
+
p = Person.new(:name => 'McLovin', :age => 12)
|
34
|
+
p.name.should == 'McLovin'
|
35
|
+
p.age.should == 12
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "SuperModel::Base #new method with a block (and self being passed to the block)" do
|
40
|
+
before(:all) do
|
41
|
+
class Dog < SuperModel::Base
|
42
|
+
has :name
|
43
|
+
has :age, :which_is => :number
|
44
|
+
has :collar
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
after(:all) do
|
49
|
+
Object.send(:remove_const, :Dog)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be able to initialize all the attributes correctly" do
|
53
|
+
dog = Dog.new do |d|
|
54
|
+
d.name = "Buster"
|
55
|
+
d.age = 2
|
56
|
+
d.collar = "Stray"
|
57
|
+
end
|
58
|
+
|
59
|
+
dog.name.should == "Buster"
|
60
|
+
dog.age.should == 2
|
61
|
+
dog.collar.should == "Stray"
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "SuperModel::Base #marshal_dump method with just simple attributes" do
|
4
|
+
before(:each) do
|
5
|
+
class Hotel < SuperModel::Base
|
6
|
+
has :name, :which_is => :text, :with_default_value => "Swissotel The Stamford"
|
7
|
+
has :star_rating, :which_is => :decimal, :with_default_value => 5.0
|
8
|
+
has :rooms, :which_is => :number, :with_default_value => 100
|
9
|
+
end
|
10
|
+
|
11
|
+
@h = Hotel.new
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:each) do
|
15
|
+
Object.send(:remove_const, :Hotel)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have to the marshal_dump method" do
|
19
|
+
@h.should respond_to(:marshal_dump)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should produce valid JSON output when sent the marshal_dump method" do
|
23
|
+
@h.stub!(:to_json).and_return("Deflated JSON")
|
24
|
+
@h.marshal_dump.should == 'Deflated JSON'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should produce valid JSON output when an attribute has been changed and the marshal_dump method is sent" do
|
28
|
+
@h.rooms = 200
|
29
|
+
@h.stub!(:to_json).and_return("Deflated JSON, Part deux")
|
30
|
+
@h.marshal_dump.should == 'Deflated JSON, Part deux'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "SuperModel::Base #marshal_dump with associations" do
|
35
|
+
before(:each) do
|
36
|
+
class Hospital < SuperModel::Base
|
37
|
+
has :name
|
38
|
+
end
|
39
|
+
|
40
|
+
class CrazyPerson < SuperModel::Base
|
41
|
+
has :name, :which_is => :text, :with_default_value => "Crazed McLovin"
|
42
|
+
has_many :hospitals
|
43
|
+
end
|
44
|
+
|
45
|
+
@c = CrazyPerson.new
|
46
|
+
|
47
|
+
@h1 = Hospital.new(:name => "Crazy Hospital 1")
|
48
|
+
@h2 = Hospital.new(:name => "Crazy Hospital 2")
|
49
|
+
|
50
|
+
@c.add_hospital(@h1)
|
51
|
+
@c.add_hospital(@h2)
|
52
|
+
end
|
53
|
+
|
54
|
+
after(:each) do
|
55
|
+
Object.send(:remove_const, :Hospital)
|
56
|
+
Object.send(:remove_const, :CrazyPerson)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should produce valid JSON when sent the marshal_dump method" do
|
60
|
+
# Stub the deflate method, which will basically give us the gzip'd JSON
|
61
|
+
@c.stub!(:to_json).and_return("Deflated JSON, Part three")
|
62
|
+
@c.marshal_dump.should == 'Deflated JSON, Part three'
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "SuperModel::Base #marshal_load method, with many attributes" do
|
4
|
+
before(:all) do
|
5
|
+
class Hotel < SuperModel::Base
|
6
|
+
has :name, :which_is => :text, :with_default_value => "Swissotel The Stamford"
|
7
|
+
has :star_rating, :which_is => :decimal, :with_default_value => 5.0
|
8
|
+
has :rooms, :which_is => :number, :with_default_value => 100
|
9
|
+
end
|
10
|
+
|
11
|
+
class Hospital < SuperModel::Base
|
12
|
+
has :name
|
13
|
+
end
|
14
|
+
|
15
|
+
class CrazyPerson < SuperModel::Base
|
16
|
+
has :name, :which_is => :text, :with_default_value => "Crazed McLovin"
|
17
|
+
has_many :hospitals
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:all) do
|
22
|
+
Object.send(:remove_const, :Hotel)
|
23
|
+
Object.send(:remove_const, :Hospital)
|
24
|
+
Object.send(:remove_const, :CrazyPerson)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have the marshal_load method" do
|
28
|
+
Hotel.new.should respond_to(:marshal_load)
|
29
|
+
Hospital.new.should respond_to(:marshal_load)
|
30
|
+
CrazyPerson.new.should respond_to(:marshal_load)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should instantiate an object when sent the marshal_load method with valid json as a parameter" do
|
34
|
+
h = Hotel.new
|
35
|
+
|
36
|
+
h = h.marshal_load("{\"name\":\"Swissotel The Stamford\",\"rooms\":200,\"star_rating\":4.0}")
|
37
|
+
h.class.should == Hotel
|
38
|
+
# Check whether all attributes are set correctly
|
39
|
+
h.name.should == "Swissotel The Stamford"
|
40
|
+
h.rooms.should == 200
|
41
|
+
h.star_rating.should == 4.0
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should instantiate an object when sent the marshal_load method with valid JSON (containing associations) as a parameter" do
|
45
|
+
|
46
|
+
crazy = CrazyPerson.new.marshal_load('{"name":"Crazed McLovin","hospitals":[{"name":"Crazy Hospital 1"},{"name":"Crazy Hospital 2"}]}')
|
47
|
+
crazy.class.should == CrazyPerson
|
48
|
+
|
49
|
+
crazy.name == "Crazed McLovin"
|
50
|
+
crazy.hospitals.size.should == 2
|
51
|
+
|
52
|
+
hospitals = crazy.hospitals.collect{|h| h.name }
|
53
|
+
hospitals.sort!
|
54
|
+
|
55
|
+
hospitals.first.should == 'Crazy Hospital 1'
|
56
|
+
hospitals.last.should == 'Crazy Hospital 2'
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "A Cheezburger subclass of SuperModel::Base defined in the Burgers module" do
|
4
|
+
before(:all) do
|
5
|
+
module Burgers
|
6
|
+
class Cheezburger < SuperModel::Base
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have a base_class of Burgers::Cheezburger" do
|
12
|
+
Burgers::Cheezburger.base_class.should == Burgers::Cheezburger
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "A Cheezburger subclass of SuperModel::Base nested in a Lolcat subclass of SuperModel::Base" do
|
4
|
+
before(:all) do
|
5
|
+
class Lolcat < SuperModel::Base
|
6
|
+
class Cheezburger < SuperModel::Base
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have a base_class of Lolcat::Cheezburger" do
|
12
|
+
Lolcat.base_class.should == Lolcat
|
13
|
+
Lolcat::Cheezburger.base_class.should == Lolcat::Cheezburger
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "SuperModel::Base #to_json method with just simple attributes" do
|
4
|
+
before(:each) do
|
5
|
+
class Hotel < SuperModel::Base
|
6
|
+
has :name, :which_is => :text, :with_default_value => "Swissotel The Stamford"
|
7
|
+
has :star_rating, :which_is => :decimal, :with_default_value => 5.0
|
8
|
+
has :rooms, :which_is => :number, :with_default_value => 100
|
9
|
+
end
|
10
|
+
|
11
|
+
@h = Hotel.new
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:each) do
|
15
|
+
Object.send(:remove_const, :Hotel)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have to the to_json method" do
|
19
|
+
@h.should respond_to(:to_json)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should produce valid JSON output when sent the to_json method" do
|
23
|
+
json_output = @h.to_json
|
24
|
+
# Check for JSON regex, since attributes can appear in any order
|
25
|
+
(json_output =~ /"name":"Swissotel The Stamford"/).should_not == nil
|
26
|
+
(json_output =~ /"rooms":100/).should_not == nil
|
27
|
+
(json_output =~ /"star_rating":5.0/).should_not == nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should produce valid JSON output when an attribute has been changed and the to_json method is sent" do
|
31
|
+
@h.rooms = 200
|
32
|
+
json_output = @h.to_json
|
33
|
+
# Check for JSON regex, since attributes can appear in any order
|
34
|
+
(json_output =~ /"name":"Swissotel The Stamford"/).should_not == nil
|
35
|
+
(json_output =~ /"rooms":200/).should_not == nil
|
36
|
+
(json_output =~ /"star_rating":5.0/).should_not == nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "SuperModel::Base #to_json with associations" do
|
41
|
+
before(:each) do
|
42
|
+
class Hospital < SuperModel::Base
|
43
|
+
has :name
|
44
|
+
end
|
45
|
+
|
46
|
+
class CrazyPerson < SuperModel::Base
|
47
|
+
has :name, :which_is => :text, :with_default_value => "Crazed McLovin"
|
48
|
+
has_many :hospitals
|
49
|
+
end
|
50
|
+
|
51
|
+
@c = CrazyPerson.new
|
52
|
+
|
53
|
+
@h1 = Hospital.new(:name => "Crazy Hospital 1")
|
54
|
+
@h2 = Hospital.new(:name => "Crazy Hospital 2")
|
55
|
+
|
56
|
+
@c.add_hospital(@h1)
|
57
|
+
@c.add_hospital(@h2)
|
58
|
+
end
|
59
|
+
|
60
|
+
after(:each) do
|
61
|
+
Object.send(:remove_const, :Hospital)
|
62
|
+
Object.send(:remove_const, :CrazyPerson)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should produce valid JSON when sent the to_json method" do
|
66
|
+
json_output = @c.to_json
|
67
|
+
# Check for JSON regex, since attributes can appear in any order
|
68
|
+
(json_output =~ /"name":"Crazed McLovin"/).should_not == nil
|
69
|
+
(json_output =~ /"hospitals":\[.*?\]/).should_not == nil
|
70
|
+
(json_output =~ /\{.*?"name":"Crazy Hospital 1".*?\}/).should_not == nil
|
71
|
+
(json_output =~ /\{.*?"name":"Crazy Hospital 2".*?\}/).should_not == nil
|
72
|
+
end
|
73
|
+
end
|