active_type 0.1.3 → 0.2.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.
@@ -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