active_type 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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.ruby-version +1 -0
- data/.travis.yml +16 -0
- data/LICENSE +22 -0
- data/README.md +149 -0
- data/Rakefile +37 -0
- data/active_type.gemspec +24 -0
- data/gemfiles/Gemfile.3.2 +7 -0
- data/gemfiles/Gemfile.3.2.lock +44 -0
- data/gemfiles/Gemfile.4.0 +7 -0
- data/gemfiles/Gemfile.4.0.lock +52 -0
- data/gemfiles/Gemfile.4.1 +7 -0
- data/gemfiles/Gemfile.4.1.lock +51 -0
- data/lib/active_type/extended_record/inheritance.rb +41 -0
- data/lib/active_type/extended_record.rb +27 -0
- data/lib/active_type/no_table.rb +65 -0
- data/lib/active_type/object.rb +13 -0
- data/lib/active_type/record.rb +15 -0
- data/lib/active_type/version.rb +3 -0
- data/lib/active_type/virtual_attributes.rb +166 -0
- data/lib/active_type.rb +6 -0
- data/spec/active_type/extended_record/single_table_inheritance_spec.rb +62 -0
- data/spec/active_type/extended_record_spec.rb +118 -0
- data/spec/active_type/object_spec.rb +256 -0
- data/spec/active_type/record_spec.rb +173 -0
- data/spec/integration/sign_in_spec.rb +98 -0
- data/spec/integration/sign_up_spec.rb +90 -0
- data/spec/shared_examples/accessors.rb +24 -0
- data/spec/shared_examples/belongs_to.rb +17 -0
- data/spec/shared_examples/coercible_columns.rb +203 -0
- data/spec/shared_examples/constructor.rb +30 -0
- data/spec/shared_examples/mass_assignment.rb +26 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/database.rb +31 -0
- data/spec/support/error_on.rb +12 -0
- data/spec/support/i18n.rb +1 -0
- data/spec/support/protected_params.rb +20 -0
- data/spec/support/time_zone.rb +1 -0
- metadata +141 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RecordSpec
|
4
|
+
|
5
|
+
class Record < ActiveType::Record
|
6
|
+
|
7
|
+
attribute :virtual_string, :string
|
8
|
+
attribute :virtual_integer, :integer
|
9
|
+
attribute :virtual_time, :datetime
|
10
|
+
attribute :virtual_date, :date
|
11
|
+
attribute :virtual_boolean, :boolean
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class RecordWithValidations < Record
|
16
|
+
|
17
|
+
validates :persisted_string, :presence => true
|
18
|
+
validates :virtual_string, :presence => true
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
class RecordWithOverrides < Record
|
24
|
+
|
25
|
+
attribute :overridable_test, :string
|
26
|
+
|
27
|
+
def overridable_test
|
28
|
+
super + super
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class RecordCopy < ActiveType::Record
|
34
|
+
self.table_name = 'records'
|
35
|
+
|
36
|
+
attribute :virtual_string, :string
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class OtherRecord < ActiveType::Record
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
describe ActiveType::Record do
|
46
|
+
|
47
|
+
subject { RecordSpec::Record.new }
|
48
|
+
|
49
|
+
it 'is a ActiveRecord::Base' do
|
50
|
+
subject.should be_a(ActiveRecord::Base)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'is an abstract class' do
|
54
|
+
ActiveType::Record.should be_abstract_class
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'constructors' do
|
58
|
+
subject { RecordSpec::Record }
|
59
|
+
|
60
|
+
it_should_behave_like 'ActiveRecord-like constructors', { :persisted_string => "string", :persisted_integer => 100, :persisted_time => Time.now, :persisted_date => Date.today, :persisted_boolean => true }
|
61
|
+
|
62
|
+
it_should_behave_like 'ActiveRecord-like constructors', { :virtual_string => "string", :virtual_integer => 100, :virtual_time => Time.now, :virtual_date => Date.today, :virtual_boolean => true }
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'mass assignment' do
|
67
|
+
it_should_behave_like 'ActiveRecord-like mass assignment', { :persisted_string => "string", :persisted_integer => 100, :persisted_time => Time.now, :persisted_date => Date.today, :persisted_boolean => true }
|
68
|
+
|
69
|
+
it_should_behave_like 'ActiveRecord-like mass assignment', { :virtual_string => "string", :virtual_integer => 100, :virtual_time => Time.now, :virtual_date => Date.today, :virtual_boolean => true }
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'accessors' do
|
73
|
+
it_should_behave_like 'ActiveRecord-like accessors', { :persisted_string => "string", :persisted_integer => 100, :persisted_time => Time.now, :persisted_date => Date.today, :persisted_boolean => true }
|
74
|
+
|
75
|
+
it_should_behave_like 'ActiveRecord-like accessors', { :virtual_string => "string", :virtual_integer => 100, :virtual_time => Time.now, :virtual_date => Date.today, :virtual_boolean => true }
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'overridable attributes' do
|
79
|
+
|
80
|
+
subject { RecordSpec::RecordWithOverrides.new }
|
81
|
+
|
82
|
+
it 'is possible to override attributes with super' do
|
83
|
+
subject.overridable_test = "test"
|
84
|
+
|
85
|
+
subject.overridable_test.should == "testtest"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'attribute name validation' do
|
90
|
+
it 'crashes when trying to define an invalid attribute name' do
|
91
|
+
klass = Class.new(ActiveType::Record)
|
92
|
+
expect {
|
93
|
+
klass.class_eval do
|
94
|
+
attribute :"<attr>", :string
|
95
|
+
end
|
96
|
+
}.to raise_error(ActiveType::InvalidAttributeNameError)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '.reset_column_information' do
|
101
|
+
it 'does not affect virtual attributes' do
|
102
|
+
RecordSpec::RecordCopy.new.persisted_string = "string"
|
103
|
+
RecordSpec::RecordCopy.reset_column_information
|
104
|
+
|
105
|
+
expect do
|
106
|
+
RecordSpec::RecordCopy.new.virtual_string = "string"
|
107
|
+
end.to_not raise_error
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'coercible' do
|
112
|
+
describe 'string columns' do
|
113
|
+
it_should_behave_like 'a coercible string column', :persisted_string
|
114
|
+
it_should_behave_like 'a coercible string column', :virtual_string
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'integer columns' do
|
118
|
+
it_should_behave_like 'a coercible integer column', :persisted_integer
|
119
|
+
it_should_behave_like 'a coercible integer column', :virtual_integer
|
120
|
+
end
|
121
|
+
|
122
|
+
describe 'date columns' do
|
123
|
+
it_should_behave_like 'a coercible date column', :persisted_date
|
124
|
+
it_should_behave_like 'a coercible date column', :virtual_date
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'time columns' do
|
128
|
+
it_should_behave_like 'a coercible time column', :persisted_time
|
129
|
+
it_should_behave_like 'a coercible time column', :virtual_time
|
130
|
+
end
|
131
|
+
|
132
|
+
describe 'boolean columns' do
|
133
|
+
it_should_behave_like 'a coercible boolean column', :persisted_boolean
|
134
|
+
it_should_behave_like 'a coercible boolean column', :virtual_boolean
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'validations' do
|
139
|
+
subject { RecordSpec::RecordWithValidations.new }
|
140
|
+
|
141
|
+
it { should have(1).error_on(:persisted_string) }
|
142
|
+
it { should have(1).error_on(:virtual_string) }
|
143
|
+
end
|
144
|
+
|
145
|
+
describe 'undefined columns' do
|
146
|
+
it 'raises an error when trying to access an undefined virtual attribute' do
|
147
|
+
expect do
|
148
|
+
subject.read_virtual_attribute('foo')
|
149
|
+
end.to raise_error(ActiveType::MissingAttributeError)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'persistence' do
|
154
|
+
|
155
|
+
it 'persists to the database' do
|
156
|
+
subject.persisted_string = "persisted string"
|
157
|
+
subject.save.should be_true
|
158
|
+
|
159
|
+
subject.class.find(subject.id).persisted_string.should == "persisted string"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe 'isolation' do
|
164
|
+
it 'does not let column information bleed into different models' do
|
165
|
+
record = RecordSpec::Record.new
|
166
|
+
other_record = RecordSpec::OtherRecord.new
|
167
|
+
|
168
|
+
record.should_not respond_to(:other_string)
|
169
|
+
other_record.should_not respond_to(:persisted_string)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SignInSpec
|
4
|
+
|
5
|
+
class SignIn < ActiveType::Object
|
6
|
+
attribute :email, :string
|
7
|
+
attribute :password, :string
|
8
|
+
|
9
|
+
validates :email, :presence => true
|
10
|
+
validates :password, :presence => true
|
11
|
+
|
12
|
+
validate :if => :password do |sign_in|
|
13
|
+
errors.add(:password, 'is not correct') unless sign_in.password == "correct password"
|
14
|
+
end
|
15
|
+
|
16
|
+
after_save :set_session
|
17
|
+
|
18
|
+
def set_session
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe SignInSpec::SignIn do
|
25
|
+
|
26
|
+
describe 'with missing credentials' do
|
27
|
+
|
28
|
+
it 'is invalid' do
|
29
|
+
subject.should_not be_valid
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has errors' do
|
33
|
+
subject.valid?
|
34
|
+
subject.errors[:email].should == ["can't be blank"]
|
35
|
+
subject.errors[:password].should == ["can't be blank"]
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not save' do
|
39
|
+
subject.save.should be_false
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not set the session' do
|
43
|
+
subject.should_not_receive :set_session
|
44
|
+
subject.save
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'with invalid credentials' do
|
50
|
+
|
51
|
+
before do
|
52
|
+
subject.email = "email"
|
53
|
+
subject.password = "incorrect password"
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'is invalid' do
|
57
|
+
subject.should_not be_valid
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'has errors' do
|
61
|
+
subject.valid?
|
62
|
+
subject.errors[:password].should == ["is not correct"]
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'does not save' do
|
66
|
+
subject.save.should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'does not set the session' do
|
70
|
+
subject.should_not_receive :set_session
|
71
|
+
subject.save
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'with valid credentials' do
|
77
|
+
|
78
|
+
before do
|
79
|
+
subject.email = "email"
|
80
|
+
subject.password = "correct password"
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'is invalid' do
|
84
|
+
subject.should be_valid
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'does save' do
|
88
|
+
subject.save.should be_true
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'sets the session' do
|
92
|
+
subject.should_receive :set_session
|
93
|
+
subject.save
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module SignUpSpec
|
4
|
+
|
5
|
+
class User < ActiveType::Record
|
6
|
+
validates :email, :presence => true
|
7
|
+
validates :password, :presence => true
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
class SignUp < ActiveType::Record[User]
|
12
|
+
attribute :terms, :boolean
|
13
|
+
|
14
|
+
validates :terms, :acceptance => {:allow_nil => false, :accept => true}
|
15
|
+
|
16
|
+
after_create :send_welcome_email
|
17
|
+
|
18
|
+
def send_welcome_email
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe SignUpSpec::User do
|
26
|
+
|
27
|
+
it 'is valid without a password confirmation' do
|
28
|
+
subject.email = "email"
|
29
|
+
subject.password = "password"
|
30
|
+
|
31
|
+
subject.should be_valid
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
describe SignUpSpec::SignUp do
|
38
|
+
|
39
|
+
it 'is invalid without an email' do
|
40
|
+
subject.password = "password"
|
41
|
+
subject.terms = true
|
42
|
+
|
43
|
+
subject.should_not be_valid
|
44
|
+
subject.errors['email'].should == ["can't be blank"]
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'is invalid without accepted terms' do
|
48
|
+
subject.email = "email"
|
49
|
+
subject.password = "password"
|
50
|
+
|
51
|
+
subject.should_not be_valid
|
52
|
+
subject.errors['terms'].should == ["must be accepted"]
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with invalid data' do
|
56
|
+
|
57
|
+
it 'does not save' do
|
58
|
+
subject.save.should be_false
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'does not send an email' do
|
62
|
+
subject.should_not_receive :send_welcome_email
|
63
|
+
subject.save
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with valid data' do
|
69
|
+
|
70
|
+
before do
|
71
|
+
subject.email = "email"
|
72
|
+
subject.password = "password"
|
73
|
+
subject.terms = "1"
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'does save' do
|
77
|
+
subject.valid?
|
78
|
+
subject.save.should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'sends the email' do
|
82
|
+
subject.should_receive :send_welcome_email
|
83
|
+
|
84
|
+
subject.save
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
shared_examples_for "ActiveRecord-like accessors" do |attributes|
|
2
|
+
|
3
|
+
it 'allows to read and write' do
|
4
|
+
attributes.each do |key, value|
|
5
|
+
subject.send("#{key}=", value)
|
6
|
+
subject.send(key).should == value
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'allows to read via []' do
|
11
|
+
attributes.each do |key, value|
|
12
|
+
subject.send("#{key}=", value)
|
13
|
+
subject[key].should == value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'allows to write via []=' do
|
18
|
+
attributes.each do |key, value|
|
19
|
+
subject[key] = value
|
20
|
+
subject.send(key).should == value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
shared_examples_for 'a belongs_to association' do |association, klass|
|
2
|
+
|
3
|
+
let(:record) { klass.create }
|
4
|
+
|
5
|
+
it 'sets the id when assigning a record' do
|
6
|
+
subject.send("#{association}=", record)
|
7
|
+
|
8
|
+
subject.send("#{association}_id").should == record.id
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'sets the record when assigning an id' do
|
12
|
+
subject.send("#{association}_id=", record.id)
|
13
|
+
|
14
|
+
subject.send("#{association}").should == record
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
module TimeConversionSpec
|
2
|
+
class Record < ActiveRecord::Base
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
shared_examples_for 'a coercible string column' do |column|
|
7
|
+
|
8
|
+
it 'is nil by default' do
|
9
|
+
subject.send(column).should be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'leaves strings alone' do
|
13
|
+
subject.send(:"#{column}=", "string")
|
14
|
+
|
15
|
+
subject.send(column).should == "string"
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'does not convert blank' do
|
19
|
+
subject.send(:"#{column}=", "")
|
20
|
+
|
21
|
+
subject.send(column).should == ""
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
shared_examples_for 'a coercible integer column' do |column|
|
28
|
+
|
29
|
+
it 'is nil by default' do
|
30
|
+
subject.send(column).should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'leaves integers alone' do
|
34
|
+
subject.send(:"#{column}=", 10)
|
35
|
+
|
36
|
+
subject.send(column).should == 10
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'converts strings to integers' do
|
40
|
+
subject.send(:"#{column}=", "10")
|
41
|
+
|
42
|
+
subject.send(column).should == 10
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'converts blank to nil' do
|
46
|
+
subject.send(:"#{column}=", "")
|
47
|
+
|
48
|
+
subject.send(column).should be_nil
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
shared_examples_for 'a coercible date column' do |column|
|
55
|
+
|
56
|
+
it 'is nil by default' do
|
57
|
+
subject.send(column).should be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'leaves dates alone' do
|
61
|
+
date = Date.today
|
62
|
+
subject.send(:"#{column}=", date)
|
63
|
+
|
64
|
+
subject.send(column).should == date
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'converts strings to dates' do
|
68
|
+
subject.send(:"#{column}=", "2010-10-01")
|
69
|
+
|
70
|
+
subject.send(column).should == Date.new(2010, 10, 1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'converts blank to nil' do
|
74
|
+
subject.send(:"#{column}=", "")
|
75
|
+
|
76
|
+
subject.send(column).should be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
shared_examples_for 'a coercible time column' do |column|
|
83
|
+
|
84
|
+
around do |example|
|
85
|
+
begin
|
86
|
+
old_time_zone = Time.zone
|
87
|
+
old_time_zone_aware_attributes = ActiveRecord::Base.time_zone_aware_attributes
|
88
|
+
old_default_timezone = ActiveRecord::Base.default_timezone
|
89
|
+
example.run
|
90
|
+
ensure
|
91
|
+
Time.zone = old_time_zone
|
92
|
+
ActiveRecord::Base.time_zone_aware_attributes = old_time_zone_aware_attributes
|
93
|
+
ActiveRecord::Base.default_timezone = old_default_timezone
|
94
|
+
subject.class.reset_column_information
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def it_should_convert_like_active_record(column)
|
99
|
+
time = "2010-10-01 12:15"
|
100
|
+
TimeConversionSpec::Record.reset_column_information
|
101
|
+
subject.class.reset_column_information
|
102
|
+
|
103
|
+
comparison = TimeConversionSpec::Record.new
|
104
|
+
subject.send(:"#{column}=", time)
|
105
|
+
comparison.persisted_time = time
|
106
|
+
|
107
|
+
result = subject.send(column)
|
108
|
+
result.should == comparison.persisted_time
|
109
|
+
result.zone.should == comparison.persisted_time.zone
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
it 'is nil by default' do
|
114
|
+
subject.send(column).should be_nil
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'leaves times alone' do
|
118
|
+
time = Time.now
|
119
|
+
subject.send(:"#{column}=", time)
|
120
|
+
|
121
|
+
subject.send(column).should == time
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'converts strings to times' do
|
125
|
+
subject.send(:"#{column}=", "2010-10-01 12:15")
|
126
|
+
|
127
|
+
subject.send(column).should == Time.new(2010, 10, 1, 12, 15)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'behaves consistently with ActiveRecord' do
|
131
|
+
Time.zone = 'Hawaii'
|
132
|
+
|
133
|
+
it_should_convert_like_active_record(column)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'behaves consistently with ActiveRecord if time_zone_aware_attributes is set' do
|
137
|
+
Time.zone = 'Hawaii'
|
138
|
+
ActiveRecord::Base.time_zone_aware_attributes = true
|
139
|
+
|
140
|
+
it_should_convert_like_active_record(column)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'behaves consistently with ActiveRecord if default_timezone is :utc' do
|
144
|
+
Time.zone = 'Hawaii'
|
145
|
+
ActiveRecord::Base.default_timezone = :utc
|
146
|
+
|
147
|
+
it_should_convert_like_active_record(column)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'behaves consistently with ActiveRecord if time_zone_aware_attributes is set, default_timezone is :utc' do
|
151
|
+
Time.zone = 'Hawaii'
|
152
|
+
ActiveRecord::Base.default_timezone = :utc
|
153
|
+
ActiveRecord::Base.time_zone_aware_attributes = true
|
154
|
+
|
155
|
+
it_should_convert_like_active_record(column)
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
shared_examples_for 'a coercible boolean column' do |column|
|
162
|
+
|
163
|
+
it 'is nil by default' do
|
164
|
+
subject.send(column).should be_nil
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'leaves booleans alone' do
|
168
|
+
subject.send(:"#{column}=", true)
|
169
|
+
|
170
|
+
subject.send(column).should == true
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'converts 1 to true' do
|
174
|
+
subject.send(:"#{column}=", "1")
|
175
|
+
|
176
|
+
subject.send(column).should == true
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'converts 0 to false' do
|
180
|
+
subject.send(:"#{column}=", "0")
|
181
|
+
|
182
|
+
subject.send(column).should == false
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'converts "" to nil' do
|
186
|
+
subject.send(:"#{column}=", "")
|
187
|
+
|
188
|
+
subject.send(column).should be_nil
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'converts "true" to true' do
|
192
|
+
subject.send(:"#{column}=", "true")
|
193
|
+
|
194
|
+
subject.send(column).should == true
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'converts "false" to false' do
|
198
|
+
subject.send(:"#{column}=", "false")
|
199
|
+
|
200
|
+
subject.send(column).should == false
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
shared_examples_for 'ActiveRecord-like constructors' do |attributes|
|
2
|
+
|
3
|
+
it 'return a new record' do
|
4
|
+
subject.new.should be_new_record
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'assigns given attributes' do
|
8
|
+
record = subject.new(attributes)
|
9
|
+
|
10
|
+
attributes.each do |key, value|
|
11
|
+
record.send(key).should == value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
16
|
+
|
17
|
+
it 'raises on unpermitted parameters' do
|
18
|
+
params = ProtectedParams.new(attributes)
|
19
|
+
expect { subject.new(params) }.to raise_error(ActiveModel::ForbiddenAttributesError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'accepts permitted parameters' do
|
23
|
+
params = ProtectedParams.new(attributes)
|
24
|
+
params.permit!
|
25
|
+
expect { subject.new(params) }.to_not raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
shared_examples_for 'ActiveRecord-like mass assignment' do |attributes|
|
2
|
+
|
3
|
+
it 'assigns all given attributes' do
|
4
|
+
subject.attributes = attributes
|
5
|
+
|
6
|
+
attributes.each do |key, value|
|
7
|
+
subject.send(key).should == value
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
12
|
+
|
13
|
+
it 'raises on unpermitted parameters' do
|
14
|
+
params = ProtectedParams.new(attributes)
|
15
|
+
expect { subject.attributes = params }.to raise_error(ActiveModel::ForbiddenAttributesError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'accepts permitted parameters' do
|
19
|
+
params = ProtectedParams.new(attributes)
|
20
|
+
params.permit!
|
21
|
+
expect { subject.attributes = params }.to_not raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$: << File.join(File.dirname(__FILE__), "/../../lib" )
|
4
|
+
|
5
|
+
require 'active_record'
|
6
|
+
require 'active_type'
|
7
|
+
|
8
|
+
ActiveRecord::Base.default_timezone = :local
|
9
|
+
|
10
|
+
Dir["#{File.dirname(__FILE__)}/support/*"].each {|f| require f}
|
11
|
+
Dir["#{File.dirname(__FILE__)}/shared_examples/*"].each {|f| require f}
|
12
|
+
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.around do |example|
|
16
|
+
ActiveRecord::Base.transaction do
|
17
|
+
begin
|
18
|
+
example.run
|
19
|
+
ensure
|
20
|
+
raise ActiveRecord::Rollback
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|