active_type 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -40,6 +40,17 @@ module RecordSpec
40
40
 
41
41
  class OtherRecord < ActiveType::Record
42
42
  end
43
+
44
+ class Child < ActiveRecord::Base
45
+ end
46
+
47
+ class RecordWithBelongsTo < Record
48
+
49
+ attribute :child_id, :integer
50
+
51
+ belongs_to :child
52
+
53
+ end
43
54
  end
44
55
 
45
56
 
@@ -180,6 +191,10 @@ describe ActiveType::Record do
180
191
  end
181
192
  end
182
193
 
194
+ describe 'defaults' do
195
+ it_should_behave_like "a class accepting attribute defaults", RecordSpec::Record
196
+ end
197
+
183
198
  describe 'persistence' do
184
199
 
185
200
  it 'persists to the database' do
@@ -200,4 +215,10 @@ describe ActiveType::Record do
200
215
  end
201
216
  end
202
217
 
218
+ describe '#belongs_to' do
219
+ subject { RecordSpec::RecordWithBelongsTo.new }
220
+
221
+ it_should_behave_like 'a belongs_to association', :child, RecordSpec::Child
222
+ end
223
+
203
224
  end
@@ -0,0 +1,102 @@
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
+ form.holidays.collect(&:name).should == ["New Year", "Epiphany"]
55
+ end
56
+
57
+ it 'can create a list of holidays' do
58
+ update(params).should be_true
59
+
60
+ holidays = HolidaySpec::Holiday.order(:date)
61
+ holidays.collect(&:name).should == ["New Year", "Epiphany"]
62
+ holidays.collect(&:date).should == [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
+ update(params).should be_true
71
+
72
+ holidays = HolidaySpec::Holiday.order(:date)
73
+ holidays.collect(&:name).should == ["New Year 2014", "Epiphany 2014"]
74
+ holidays.collect(&:date).should == [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
+ update(params).should be_true
82
+
83
+ holidays = HolidaySpec::Holiday.order(:date)
84
+ holidays.collect(&:name).should == ["Epiphany"]
85
+ holidays.collect(&:date).should == [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
+ update(params).should be_false
95
+
96
+ holidays = HolidaySpec::Holiday.order(:date)
97
+ holidays.collect(&:name).should == ["New Year", "Epiphany"]
98
+ holidays.collect(&:date).should == [Date.civil(2014, 1, 1), Date.civil(2014, 1, 6)]
99
+ end
100
+
101
+
102
+ end
@@ -0,0 +1,112 @@
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
+ if form.save
59
+ params['id'] = form.child.id
60
+ end
61
+ end
62
+
63
+ it 'can create a circle' do
64
+ params = {
65
+ 'type' => 'circle',
66
+ 'radius' => '20'
67
+ }.with_indifferent_access
68
+
69
+ update(params).should be_true
70
+
71
+ ShapeSpec::Circle.all.collect(&:radius).should == [20]
72
+ ShapeSpec::Rectangle.count.should == 0
73
+ end
74
+
75
+ it 'can create a rectangle' do
76
+ params = {
77
+ 'type' => 'rectangle',
78
+ 'length' => '100',
79
+ 'width' => '30'
80
+ }.with_indifferent_access
81
+
82
+ update(params).should be_true
83
+
84
+ ShapeSpec::Circle.count.should == 0
85
+ ShapeSpec::Rectangle.all.collect(&:length).should == [100]
86
+ ShapeSpec::Rectangle.all.collect(&:width).should == [30]
87
+ end
88
+
89
+ it 'can update' do
90
+ params = {
91
+ 'type' => 'circle',
92
+ 'radius' => '20'
93
+ }.with_indifferent_access
94
+ update(params)
95
+
96
+ params['radius'] = '30'
97
+ update(params).should be_true
98
+
99
+ ShapeSpec::Circle.all.collect(&:radius).should == [30]
100
+ end
101
+
102
+ it 'has validations' do
103
+ params = {
104
+ 'type' => 'circle'
105
+ }.with_indifferent_access
106
+
107
+ update(params).should be_false
108
+
109
+ form.child.errors['radius'].should == ["can't be blank"]
110
+ end
111
+
112
+ end
@@ -1,3 +1,6 @@
1
+ # Usecase: implement a sign in form
2
+ # The sign in is not tied to a database record
3
+
1
4
  require 'spec_helper'
2
5
 
3
6
  module SignInSpec
@@ -1,5 +1,17 @@
1
+ # Usecase: implement a sign up form
2
+ # The sign up is tied to a user model
3
+
4
+
1
5
  require 'spec_helper'
2
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
+
3
15
  module SignUpSpec
4
16
 
5
17
  class User < ActiveType::Record
@@ -0,0 +1,60 @@
1
+ shared_examples_for "a class accepting attribute defaults" do |klass|
2
+
3
+ subject do
4
+ Class.new(klass) do
5
+ attribute :static_string, :string, :default => "static string"
6
+ attribute :dynamic_string, :string, :default => proc { "dynamic string" }
7
+ attribute :referential_string, :string, :default => proc { value }
8
+ attribute :number, :integer, :default => "10"
9
+ attribute :computed, :default => proc { compute }
10
+
11
+ def value
12
+ "value"
13
+ end
14
+
15
+ end.new
16
+ end
17
+
18
+ it 'can have static defaults' do
19
+ subject.static_string.should == "static string"
20
+ end
21
+
22
+ it 'can have dynamic defaults' do
23
+ subject.dynamic_string.should == "dynamic string"
24
+ end
25
+
26
+ it 'can have defaults refering to instance methods' do
27
+ subject.referential_string.should == "value"
28
+ end
29
+
30
+ it 'typecasts defaults' do
31
+ subject.number.should == 10
32
+ end
33
+
34
+ it 'computes defaults lazily' do
35
+ subject.should_receive(:compute).and_return("computed")
36
+ subject.computed.should == "computed"
37
+ end
38
+
39
+ it 'does not compute defaults more than once' do
40
+ subject.should_receive(:compute).exactly(:once).and_return(nil)
41
+ subject.computed
42
+ subject.computed
43
+ end
44
+
45
+ it 'does not compute defaults when overriden' do
46
+ subject.computed = 'not computed'
47
+ subject.computed.should == 'not computed'
48
+ end
49
+
50
+ it 'does not use defaults when overriden' do
51
+ subject.static_string = "my string"
52
+ subject.static_string.should == "my string"
53
+ end
54
+
55
+ it 'does not use defaults when overriden with nil' do
56
+ subject.static_string = nil
57
+ subject.static_string.should == nil
58
+ end
59
+
60
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  $: << File.join(File.dirname(__FILE__), "/../../lib" )
4
4
 
5
- require 'active_record'
6
5
  require 'active_type'
7
6
 
8
7
  ActiveRecord::Base.default_timezone = :local
@@ -23,9 +23,4 @@ ActiveRecord::Migration.class_eval do
23
23
  t.string :other_string
24
24
  end
25
25
 
26
- create_table :users do |t|
27
- t.string :email
28
- t.string :password
29
- end
30
-
31
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Kraze
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-21 00:00:00.000000000 Z
12
+ date: 2014-08-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -75,6 +75,11 @@ files:
75
75
  - lib/active_type.rb
76
76
  - lib/active_type/extended_record.rb
77
77
  - lib/active_type/extended_record/inheritance.rb
78
+ - lib/active_type/nested_attributes.rb
79
+ - lib/active_type/nested_attributes/association.rb
80
+ - lib/active_type/nested_attributes/builder.rb
81
+ - lib/active_type/nested_attributes/nests_many_association.rb
82
+ - lib/active_type/nested_attributes/nests_one_association.rb
78
83
  - lib/active_type/no_table.rb
79
84
  - lib/active_type/object.rb
80
85
  - lib/active_type/record.rb
@@ -82,14 +87,18 @@ files:
82
87
  - lib/active_type/virtual_attributes.rb
83
88
  - spec/active_type/extended_record/single_table_inheritance_spec.rb
84
89
  - spec/active_type/extended_record_spec.rb
90
+ - spec/active_type/nested_attributes_spec.rb
85
91
  - spec/active_type/object_spec.rb
86
92
  - spec/active_type/record_spec.rb
93
+ - spec/integration/holidays_spec.rb
94
+ - spec/integration/shape_spec.rb
87
95
  - spec/integration/sign_in_spec.rb
88
96
  - spec/integration/sign_up_spec.rb
89
97
  - spec/shared_examples/accessors.rb
90
98
  - spec/shared_examples/belongs_to.rb
91
99
  - spec/shared_examples/coercible_columns.rb
92
100
  - spec/shared_examples/constructor.rb
101
+ - spec/shared_examples/defaults.rb
93
102
  - spec/shared_examples/mass_assignment.rb
94
103
  - spec/spec_helper.rb
95
104
  - spec/support/database.rb
@@ -117,21 +126,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
126
  version: '0'
118
127
  requirements: []
119
128
  rubyforge_project:
120
- rubygems_version: 2.1.11
129
+ rubygems_version: 2.2.2
121
130
  signing_key:
122
131
  specification_version: 4
123
132
  summary: Make any Ruby object quack like ActiveRecord
124
133
  test_files:
125
134
  - spec/active_type/extended_record/single_table_inheritance_spec.rb
126
135
  - spec/active_type/extended_record_spec.rb
136
+ - spec/active_type/nested_attributes_spec.rb
127
137
  - spec/active_type/object_spec.rb
128
138
  - spec/active_type/record_spec.rb
139
+ - spec/integration/holidays_spec.rb
140
+ - spec/integration/shape_spec.rb
129
141
  - spec/integration/sign_in_spec.rb
130
142
  - spec/integration/sign_up_spec.rb
131
143
  - spec/shared_examples/accessors.rb
132
144
  - spec/shared_examples/belongs_to.rb
133
145
  - spec/shared_examples/coercible_columns.rb
134
146
  - spec/shared_examples/constructor.rb
147
+ - spec/shared_examples/defaults.rb
135
148
  - spec/shared_examples/mass_assignment.rb
136
149
  - spec/spec_helper.rb
137
150
  - spec/support/database.rb