active_type 0.4.5 → 0.7.5
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 +4 -4
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.travis.yml +30 -24
- data/CHANGELOG.md +73 -2
- data/README.md +56 -11
- data/Rakefile +22 -1
- data/active_type.gemspec +2 -1
- data/gemfiles/Gemfile.3.2.mysql2 +1 -0
- data/gemfiles/Gemfile.3.2.mysql2.lock +4 -2
- data/gemfiles/Gemfile.3.2.sqlite3 +1 -0
- data/gemfiles/Gemfile.3.2.sqlite3.lock +4 -2
- data/gemfiles/Gemfile.4.0.sqlite3 +1 -0
- data/gemfiles/Gemfile.4.0.sqlite3.lock +4 -2
- data/gemfiles/Gemfile.4.1.sqlite3 +1 -0
- data/gemfiles/Gemfile.4.1.sqlite3.lock +4 -2
- data/gemfiles/Gemfile.4.2.1.mysql2 +1 -0
- data/gemfiles/Gemfile.4.2.1.mysql2.lock +4 -2
- data/gemfiles/Gemfile.4.2.1.pg +1 -0
- data/gemfiles/Gemfile.4.2.1.pg.lock +4 -2
- data/gemfiles/Gemfile.4.2.1.sqlite3 +1 -0
- data/gemfiles/Gemfile.4.2.1.sqlite3.lock +4 -2
- data/gemfiles/Gemfile.5.0.0.mysql2.lock +56 -0
- data/gemfiles/Gemfile.5.0.0.pg.lock +56 -0
- data/gemfiles/Gemfile.5.0.0.sqlite3 +8 -0
- data/gemfiles/Gemfile.5.0.0.sqlite3.lock +56 -0
- data/gemfiles/Gemfile.5.1.0.mysql2 +8 -0
- data/gemfiles/Gemfile.5.1.0.mysql2.lock +56 -0
- data/gemfiles/Gemfile.5.1.0.pg +8 -0
- data/gemfiles/Gemfile.5.1.0.pg.lock +56 -0
- data/gemfiles/Gemfile.5.1.0.sqlite3 +8 -0
- data/gemfiles/Gemfile.5.1.0.sqlite3.lock +56 -0
- data/lib/active_type/extended_record/inheritance.rb +41 -6
- data/lib/active_type/nested_attributes/association.rb +13 -4
- data/lib/active_type/nested_attributes/builder.rb +3 -3
- data/lib/active_type/nested_attributes/nests_many_association.rb +5 -1
- data/lib/active_type/nested_attributes/nests_one_association.rb +3 -2
- data/lib/active_type/no_table.rb +129 -42
- data/lib/active_type/type_caster.rb +66 -25
- data/lib/active_type/util.rb +21 -6
- data/lib/active_type/version.rb +1 -1
- data/lib/active_type/virtual_attributes.rb +23 -1
- data/lib/active_type.rb +13 -3
- metadata +16 -55
- data/spec/active_type/extended_record/single_table_inheritance_spec.rb +0 -62
- data/spec/active_type/extended_record_spec.rb +0 -233
- data/spec/active_type/nested_attributes_spec.rb +0 -700
- data/spec/active_type/object_spec.rb +0 -400
- data/spec/active_type/record_spec.rb +0 -236
- data/spec/active_type/util_spec.rb +0 -128
- data/spec/integration/holidays_spec.rb +0 -102
- data/spec/integration/shape_spec.rb +0 -110
- data/spec/integration/sign_in_spec.rb +0 -101
- data/spec/integration/sign_up_spec.rb +0 -102
- data/spec/shared_examples/accessors.rb +0 -41
- data/spec/shared_examples/belongs_to.rb +0 -17
- data/spec/shared_examples/coercible_columns.rb +0 -228
- data/spec/shared_examples/constructor.rb +0 -30
- data/spec/shared_examples/defaults.rb +0 -60
- data/spec/shared_examples/dirty_tracking.rb +0 -40
- data/spec/shared_examples/dupable.rb +0 -31
- data/spec/shared_examples/mass_assignment.rb +0 -26
- data/spec/spec_helper.rb +0 -27
- data/spec/support/database.rb +0 -55
- data/spec/support/database.sample.yml +0 -3
- data/spec/support/error_on.rb +0 -12
- data/spec/support/i18n.rb +0 -1
- data/spec/support/protected_params.rb +0 -20
- data/spec/support/time_zone.rb +0 -1
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module UtilSpec
|
4
|
-
|
5
|
-
class BaseRecord < ActiveRecord::Base
|
6
|
-
self.table_name = 'records'
|
7
|
-
end
|
8
|
-
|
9
|
-
class ExtendedRecord < ActiveType::Record[BaseRecord]
|
10
|
-
|
11
|
-
attribute :virtual_string
|
12
|
-
after_initialize :set_virtual_string
|
13
|
-
|
14
|
-
def set_virtual_string
|
15
|
-
self.virtual_string = "persisted_string is #{persisted_string}"
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
class Parent < ActiveRecord::Base
|
21
|
-
self.table_name = 'sti_records'
|
22
|
-
end
|
23
|
-
|
24
|
-
class Child < Parent
|
25
|
-
end
|
26
|
-
|
27
|
-
class ChildSibling < Parent
|
28
|
-
end
|
29
|
-
|
30
|
-
class ExtendedChild < ActiveType::Record[Child]
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
describe ActiveType::Util do
|
36
|
-
|
37
|
-
describe '.cast' do
|
38
|
-
|
39
|
-
describe 'for a relation' do
|
40
|
-
|
41
|
-
it 'casts a scope to a scope of another class' do
|
42
|
-
record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
43
|
-
base_scope = UtilSpec::BaseRecord.where(:persisted_string => 'foo')
|
44
|
-
casted_scope = ActiveType::Util.cast(base_scope, UtilSpec::ExtendedRecord)
|
45
|
-
expect(casted_scope.build).to be_a(UtilSpec::ExtendedRecord)
|
46
|
-
found_record = casted_scope.find(record.id)
|
47
|
-
expect(found_record.persisted_string).to eq('foo')
|
48
|
-
expect(found_record).to be_a(UtilSpec::ExtendedRecord)
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'preserves existing scope conditions' do
|
52
|
-
match = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
53
|
-
no_match = UtilSpec::BaseRecord.create!(:persisted_string => 'bar')
|
54
|
-
base_scope = UtilSpec::BaseRecord.where(:persisted_string => 'foo')
|
55
|
-
casted_scope = ActiveType::Util.cast(base_scope, UtilSpec::ExtendedRecord)
|
56
|
-
casted_match = UtilSpec::ExtendedRecord.find(match.id)
|
57
|
-
expect(casted_scope.to_a).to eq([casted_match])
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
describe 'for a record type' do
|
63
|
-
|
64
|
-
it 'casts a base record to an extended record' do
|
65
|
-
base_record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
66
|
-
extended_record = ActiveType::Util.cast(base_record, UtilSpec::ExtendedRecord)
|
67
|
-
expect(extended_record).to be_a(UtilSpec::ExtendedRecord)
|
68
|
-
expect(extended_record).to be_persisted
|
69
|
-
expect(extended_record.id).to be_present
|
70
|
-
expect(extended_record.id).to eq(base_record.id)
|
71
|
-
expect(extended_record.persisted_string).to eq('foo')
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'casts an extended record to a base record' do
|
75
|
-
extended_record = UtilSpec::ExtendedRecord.create!(:persisted_string => 'foo')
|
76
|
-
base_record = ActiveType::Util.cast(extended_record, UtilSpec::BaseRecord)
|
77
|
-
expect(base_record).to be_a(UtilSpec::BaseRecord)
|
78
|
-
expect(base_record).to be_persisted
|
79
|
-
expect(base_record.id).to be_present
|
80
|
-
expect(base_record.id).to eq(extended_record.id)
|
81
|
-
expect(base_record.persisted_string).to eq('foo')
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'calls after_initialize callbacks of the cast target' do
|
85
|
-
base_record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
86
|
-
extended_record = ActiveType::Util.cast(base_record, UtilSpec::ExtendedRecord)
|
87
|
-
expect(extended_record.virtual_string).to be_present
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'lets after_initialize callbacks access attributes (bug in ActiveRecord#becomes)' do
|
91
|
-
base_record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
92
|
-
extended_record = ActiveType::Util.cast(base_record, UtilSpec::ExtendedRecord)
|
93
|
-
expect(extended_record.virtual_string).to eq('persisted_string is foo')
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'preserves the #type of an STI record that is casted to an ExtendedRecord' do
|
97
|
-
child_record = UtilSpec::Child.create!(:persisted_string => 'foo')
|
98
|
-
extended_child_record = ActiveType::Util.cast(child_record, UtilSpec::ExtendedChild)
|
99
|
-
expect(extended_child_record).to be_a(UtilSpec::ExtendedChild)
|
100
|
-
expect(extended_child_record.type).to eq('UtilSpec::Child')
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'changes the #type of an STI record when casted to another type in the hierarchy' do
|
104
|
-
child_record = UtilSpec::Child.create!(:persisted_string => 'foo')
|
105
|
-
child_sibling_record = ActiveType::Util.cast(child_record, UtilSpec::ChildSibling)
|
106
|
-
expect(child_sibling_record).to be_a(UtilSpec::ChildSibling)
|
107
|
-
expect(child_sibling_record.type).to eq('UtilSpec::Child')
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'preserves dirty tracking flags' do
|
111
|
-
base_record = UtilSpec::BaseRecord.create!(:persisted_string => 'foo')
|
112
|
-
expect(base_record.changes).to eq({})
|
113
|
-
base_record.persisted_string = 'bar'
|
114
|
-
expect(base_record.changes).to eq({ 'persisted_string' => ['foo', 'bar'] })
|
115
|
-
extended_record = ActiveType::Util.cast(base_record, UtilSpec::ExtendedRecord)
|
116
|
-
expect(extended_record).to be_a(UtilSpec::ExtendedRecord)
|
117
|
-
expect(extended_record.changes).to eq({ 'persisted_string' => ['foo', 'bar'] })
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
it "exposes all methods through ActiveType's root namespace" do
|
125
|
-
expect(ActiveType).to respond_to(:cast)
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# Usecase: CRUD a number of records
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
ActiveRecord::Migration.class_eval do
|
6
|
-
create_table :holidays do |t|
|
7
|
-
t.string :name
|
8
|
-
t.date :date
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module HolidaySpec
|
13
|
-
|
14
|
-
class Holiday < ActiveRecord::Base
|
15
|
-
validates :name, :date, :presence => true
|
16
|
-
end
|
17
|
-
|
18
|
-
class HolidayForm < ActiveType::Object
|
19
|
-
nests_many :holidays, :scope => Holiday, :default => proc { Holiday.all }, :reject_if => :all_blank, :allow_destroy => true
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
describe HolidaySpec::HolidayForm do
|
26
|
-
|
27
|
-
let(:params) do
|
28
|
-
{
|
29
|
-
'1' => {
|
30
|
-
'name' => 'New Year',
|
31
|
-
'date' => '2014-01-01',
|
32
|
-
},
|
33
|
-
'2' => {
|
34
|
-
'name' => 'Epiphany',
|
35
|
-
'date' => '2014-01-06',
|
36
|
-
},
|
37
|
-
}
|
38
|
-
end
|
39
|
-
|
40
|
-
def update(params)
|
41
|
-
form = HolidaySpec::HolidayForm.new(:holidays_attributes => params)
|
42
|
-
if form.save
|
43
|
-
ids = form.holidays.collect(&:id)
|
44
|
-
params.each_with_index do |(key, attributes), index|
|
45
|
-
attributes['id'] = ids[index]
|
46
|
-
end
|
47
|
-
true
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'will return holidays including updated ones' do
|
52
|
-
HolidaySpec::Holiday.create!(:name => 'New Year', :date => '2014-01-01')
|
53
|
-
form = HolidaySpec::HolidayForm.new(:holidays_attributes => params.slice('2'))
|
54
|
-
expect(form.holidays.collect(&:name)).to eq(["New Year", "Epiphany"])
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'can create a list of holidays' do
|
58
|
-
expect(update(params)).to eq(true)
|
59
|
-
|
60
|
-
holidays = HolidaySpec::Holiday.order(:date)
|
61
|
-
expect(holidays.collect(&:name)).to eq(["New Year", "Epiphany"])
|
62
|
-
expect(holidays.collect(&:date)).to eq([Date.civil(2014, 1, 1), Date.civil(2014, 1, 6)])
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'can update holidays' do
|
66
|
-
update(params)
|
67
|
-
|
68
|
-
params['1']['name'] += ' 2014'
|
69
|
-
params['2']['name'] += ' 2014'
|
70
|
-
expect(update(params)).to eq(true)
|
71
|
-
|
72
|
-
holidays = HolidaySpec::Holiday.order(:date)
|
73
|
-
expect(holidays.collect(&:name)).to eq(["New Year 2014", "Epiphany 2014"])
|
74
|
-
expect(holidays.collect(&:date)).to eq([Date.civil(2014, 1, 1), Date.civil(2014, 1, 6)])
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'can destroy holidays' do
|
78
|
-
update(params)
|
79
|
-
|
80
|
-
params['1']['_destroy'] = '1'
|
81
|
-
expect(update(params)).to eq(true)
|
82
|
-
|
83
|
-
holidays = HolidaySpec::Holiday.order(:date)
|
84
|
-
expect(holidays.collect(&:name)).to eq(["Epiphany"])
|
85
|
-
expect(holidays.collect(&:date)).to eq([Date.civil(2014, 1, 6)])
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'will not save if some fields are invalid' do
|
89
|
-
update(params)
|
90
|
-
|
91
|
-
params['1']['name'] = '-'
|
92
|
-
params['1']['_destroy'] = '1'
|
93
|
-
params['2']['name'] = '' # invalid
|
94
|
-
expect(update(params)).to be_falsey
|
95
|
-
|
96
|
-
holidays = HolidaySpec::Holiday.order(:date)
|
97
|
-
expect(holidays.collect(&:name)).to eq(["New Year", "Epiphany"])
|
98
|
-
expect(holidays.collect(&:date)).to eq([Date.civil(2014, 1, 1), Date.civil(2014, 1, 6)])
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
# Usecase: Create a STI record, form model decides which type
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
ActiveRecord::Migration.class_eval do
|
6
|
-
create_table :shapes do |t|
|
7
|
-
t.string :type
|
8
|
-
t.integer :radius
|
9
|
-
t.integer :length
|
10
|
-
t.integer :width
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module ShapeSpec
|
15
|
-
|
16
|
-
class Shape < ActiveType::Record
|
17
|
-
end
|
18
|
-
|
19
|
-
class Circle < Shape
|
20
|
-
validates :radius, :presence => true
|
21
|
-
end
|
22
|
-
|
23
|
-
class Rectangle < Shape
|
24
|
-
validates :length, :width, :presence => true
|
25
|
-
end
|
26
|
-
|
27
|
-
class ShapeForm < ActiveType::Object
|
28
|
-
nests_one :child
|
29
|
-
|
30
|
-
def child_type=(type)
|
31
|
-
case type
|
32
|
-
when 'circle'
|
33
|
-
if child
|
34
|
-
self.child = self.child.becomes(Circle)
|
35
|
-
else
|
36
|
-
self.child = Circle.new
|
37
|
-
end
|
38
|
-
when 'rectangle'
|
39
|
-
if child
|
40
|
-
self.child = self.child.becomes(Rectangle)
|
41
|
-
else
|
42
|
-
self.child = Rectangle.new
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
describe ShapeSpec::ShapeForm do
|
52
|
-
|
53
|
-
let(:form) { ShapeSpec::ShapeForm.new }
|
54
|
-
|
55
|
-
def update(params)
|
56
|
-
form.child_type = params[:type]
|
57
|
-
form.child_attributes = params.except(:type)
|
58
|
-
form.save
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'can create a circle' do
|
62
|
-
params = {
|
63
|
-
'type' => 'circle',
|
64
|
-
'radius' => '20'
|
65
|
-
}.with_indifferent_access
|
66
|
-
|
67
|
-
expect(update(params)).to eq(true)
|
68
|
-
|
69
|
-
expect(ShapeSpec::Circle.all.collect(&:radius)).to eq([20])
|
70
|
-
expect(ShapeSpec::Rectangle.count).to eq(0)
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'can create a rectangle' do
|
74
|
-
params = {
|
75
|
-
'type' => 'rectangle',
|
76
|
-
'length' => '100',
|
77
|
-
'width' => '30'
|
78
|
-
}.with_indifferent_access
|
79
|
-
|
80
|
-
expect(update(params)).to eq(true)
|
81
|
-
|
82
|
-
expect(ShapeSpec::Circle.count).to eq(0)
|
83
|
-
expect(ShapeSpec::Rectangle.all.collect(&:length)).to eq([100])
|
84
|
-
expect(ShapeSpec::Rectangle.all.collect(&:width)).to eq([30])
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'can update' do
|
88
|
-
params = {
|
89
|
-
'type' => 'circle',
|
90
|
-
'radius' => '20'
|
91
|
-
}.with_indifferent_access
|
92
|
-
update(params)
|
93
|
-
|
94
|
-
params['radius'] = '30'
|
95
|
-
expect(update(params)).to eq(true)
|
96
|
-
|
97
|
-
expect(ShapeSpec::Circle.all.collect(&:radius)).to eq([30])
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'has validations' do
|
101
|
-
params = {
|
102
|
-
'type' => 'circle'
|
103
|
-
}.with_indifferent_access
|
104
|
-
|
105
|
-
expect(update(params)).to be_falsey
|
106
|
-
|
107
|
-
expect(form.child.errors['radius']).to eq(["can't be blank"])
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
# Usecase: implement a sign in form
|
2
|
-
# The sign in is not tied to a database record
|
3
|
-
|
4
|
-
require 'spec_helper'
|
5
|
-
|
6
|
-
module SignInSpec
|
7
|
-
|
8
|
-
class SignIn < ActiveType::Object
|
9
|
-
attribute :email, :string
|
10
|
-
attribute :password, :string
|
11
|
-
|
12
|
-
validates :email, :presence => true
|
13
|
-
validates :password, :presence => true
|
14
|
-
|
15
|
-
validate :if => :password do |sign_in|
|
16
|
-
errors.add(:password, 'is not correct') unless sign_in.password == "correct password"
|
17
|
-
end
|
18
|
-
|
19
|
-
after_save :set_session
|
20
|
-
|
21
|
-
def set_session
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
describe SignInSpec::SignIn do
|
28
|
-
|
29
|
-
describe 'with missing credentials' do
|
30
|
-
|
31
|
-
it 'is invalid' do
|
32
|
-
expect(subject).not_to be_valid
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'has errors' do
|
36
|
-
subject.valid?
|
37
|
-
expect(subject.errors[:email]).to eq(["can't be blank"])
|
38
|
-
expect(subject.errors[:password]).to eq(["can't be blank"])
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'does not save' do
|
42
|
-
expect(subject.save).to be_falsey
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'does not set the session' do
|
46
|
-
expect(subject).not_to receive :set_session
|
47
|
-
subject.save
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
describe 'with invalid credentials' do
|
53
|
-
|
54
|
-
before do
|
55
|
-
subject.email = "email"
|
56
|
-
subject.password = "incorrect password"
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'is invalid' do
|
60
|
-
expect(subject).not_to be_valid
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'has errors' do
|
64
|
-
subject.valid?
|
65
|
-
expect(subject.errors[:password]).to eq(["is not correct"])
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'does not save' do
|
69
|
-
expect(subject.save).to be_falsey
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'does not set the session' do
|
73
|
-
expect(subject).not_to receive :set_session
|
74
|
-
subject.save
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
describe 'with valid credentials' do
|
80
|
-
|
81
|
-
before do
|
82
|
-
subject.email = "email"
|
83
|
-
subject.password = "correct password"
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'is invalid' do
|
87
|
-
expect(subject).to be_valid
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'does save' do
|
91
|
-
expect(subject.save).to eq(true)
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'sets the session' do
|
95
|
-
expect(subject).to receive :set_session
|
96
|
-
subject.save
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# Usecase: implement a sign up form
|
2
|
-
# The sign up is tied to a user model
|
3
|
-
|
4
|
-
|
5
|
-
require 'spec_helper'
|
6
|
-
|
7
|
-
ActiveRecord::Migration.class_eval do
|
8
|
-
create_table :users do |t|
|
9
|
-
t.string :email
|
10
|
-
t.string :password
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
module SignUpSpec
|
16
|
-
|
17
|
-
class User < ActiveType::Record
|
18
|
-
validates :email, :presence => true
|
19
|
-
validates :password, :presence => true
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
class SignUp < ActiveType::Record[User]
|
24
|
-
attribute :terms, :boolean
|
25
|
-
|
26
|
-
validates :terms, :acceptance => {:allow_nil => false, :accept => true}
|
27
|
-
|
28
|
-
after_create :send_welcome_email
|
29
|
-
|
30
|
-
def send_welcome_email
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
describe SignUpSpec::User do
|
38
|
-
|
39
|
-
it 'is valid without a password confirmation' do
|
40
|
-
subject.email = "email"
|
41
|
-
subject.password = "password"
|
42
|
-
|
43
|
-
expect(subject).to be_valid
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
describe SignUpSpec::SignUp do
|
50
|
-
|
51
|
-
it 'is invalid without an email' do
|
52
|
-
subject.password = "password"
|
53
|
-
subject.terms = true
|
54
|
-
|
55
|
-
expect(subject).not_to be_valid
|
56
|
-
expect(subject.errors['email']).to eq(["can't be blank"])
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'is invalid without accepted terms' do
|
60
|
-
subject.email = "email"
|
61
|
-
subject.password = "password"
|
62
|
-
|
63
|
-
expect(subject).not_to be_valid
|
64
|
-
expect(subject.errors['terms']).to eq(["must be accepted"])
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'with invalid data' do
|
68
|
-
|
69
|
-
it 'does not save' do
|
70
|
-
expect(subject.save).to be_falsey
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'does not send an email' do
|
74
|
-
expect(subject).not_to receive :send_welcome_email
|
75
|
-
subject.save
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'with valid data' do
|
81
|
-
|
82
|
-
before do
|
83
|
-
subject.email = "email"
|
84
|
-
subject.password = "password"
|
85
|
-
subject.terms = "1"
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'does save' do
|
89
|
-
subject.valid?
|
90
|
-
expect(subject.save).to eq(true)
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'sends the email' do
|
94
|
-
expect(subject).to receive :send_welcome_email
|
95
|
-
|
96
|
-
subject.save
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
class User < ::ActiveRecord::Base
|
2
|
-
end
|
3
|
-
|
4
|
-
class Foo < ::ActiveType::Record[User]
|
5
|
-
def new
|
6
|
-
allocate
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
|
11
|
-
shared_examples_for "ActiveRecord-like accessors" do |attributes|
|
12
|
-
it 'setup the virtual_attributes instance variable lazy' do
|
13
|
-
expect(Foo.new.virtual_attributes).to eq({})
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'setup the virtual_attributes_cache instance variable lazy' do
|
17
|
-
expect(Foo.new.virtual_attributes_cache).to eq({})
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'allows to read and write' do
|
21
|
-
attributes.each do |key, value|
|
22
|
-
subject.send("#{key}=", value)
|
23
|
-
expect(subject.send(key)).to eq(value)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'allows to read via []' do
|
28
|
-
attributes.each do |key, value|
|
29
|
-
subject.send("#{key}=", value)
|
30
|
-
expect(subject[key]).to eq(value)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'allows to write via []=' do
|
35
|
-
attributes.each do |key, value|
|
36
|
-
subject[key] = value
|
37
|
-
expect(subject.send(key)).to eq(value)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,17 +0,0 @@
|
|
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
|
-
expect(subject.send("#{association}_id")).to eq(record.id)
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'sets the record when assigning an id' do
|
12
|
-
subject.send("#{association}_id=", record.id)
|
13
|
-
|
14
|
-
expect(subject.send("#{association}")).to eq(record)
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|