millstone 0.0.2

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.
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ class Master < ActiveRecord::Base
4
+ end
5
+
6
+ class HavingWithDeleted < ActiveRecord::Base
7
+ set_table_name 'havings'
8
+
9
+ acts_as_paranoid
10
+ belongs_to :parent, :class_name => 'ParentHasMaster', :foreign_key => 'parent_id'
11
+ belongs_to :master
12
+ end
13
+
14
+ class HavingWithoutDeleted < ActiveRecord::Base
15
+ set_table_name 'havings'
16
+
17
+ acts_as_paranoid
18
+ belongs_to :parent, :class_name => 'ParentHasMaster', :foreign_key => 'parent_id'
19
+ belongs_to :master
20
+ end
21
+
22
+ class ParentHasMaster < ActiveRecord::Base
23
+ set_table_name 'time_columns'
24
+
25
+ has_many :havings_with_deleted, :class_name => 'HavingWithDeleted', :foreign_key => 'parent_id'
26
+ has_many :havings_without_deleted, :class_name => 'HavingWithoutDeleted', :foreign_key => 'parent_id'
27
+
28
+ has_many :masters_with_deleted, :class_name => 'Master', :through => :havings_with_deleted, :source => :master, :with_deleted => true
29
+ has_many :masters_without_deleted, :class_name => 'Master', :through => :havings_without_deleted, :source => :master
30
+ end
31
+
32
+ describe Millstone::ActiveRecord::Associations::HasManyThroughWithoutDeletedAssociation do
33
+ describe ActiveRecord::Base do
34
+ let(:parent) { ParentHasMaster.create!(:context => "parent") }
35
+ let(:master1) { Master.create!(:context => "master1") }
36
+ let(:master2) { Master.create!(:context => "master2") }
37
+
38
+ describe ".has_many", ":with_deleted => false (default)" do
39
+ before do
40
+ parent.masters_without_deleted << master1
41
+ parent.masters_without_deleted << master2
42
+ parent.masters_without_deleted.delete(master2)
43
+ parent.reload
44
+ end
45
+
46
+ specify { parent.masters_without_deleted.should include master1 }
47
+ specify { parent.masters_without_deleted.should_not include master2 }
48
+ end
49
+
50
+ describe ".has_many", ":with_deleted => true" do
51
+ before do
52
+ parent.masters_with_deleted << master1
53
+ parent.masters_with_deleted << master2
54
+ parent.masters_with_deleted.delete(master2)
55
+ parent.reload
56
+ end
57
+
58
+ specify { parent.masters_with_deleted.should include master1 }
59
+ specify { parent.masters_with_deleted.should include master2 }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ class MillstoneTimeModel < ActiveRecord::Base
4
+ set_table_name 'time_columns'
5
+ millstone
6
+ end
7
+
8
+ class MillstoneBooleanModel < ActiveRecord::Base
9
+ set_table_name 'boolean_columns'
10
+ millstone :column => :deleted, :type => :boolean
11
+ end
12
+
13
+ describe Millstone::ActiveRecord::Extension do
14
+ describe ActiveRecord::Base do
15
+ let(:record) { klass.create!(:context => "name") }
16
+ let(:deleted_record) { klass.with_deleted.first }
17
+
18
+ shared_examples "execute destroy and destroy!" do
19
+ describe "#destroy" do
20
+ before { record.destroy }
21
+
22
+ specify { deleted_record.should eq record }
23
+ specify { deleted_record.should be_deleted }
24
+ end
25
+
26
+ describe "#destroy!" do
27
+ before { record.destroy! }
28
+ specify { deleted_record.should be_nil }
29
+ end
30
+ end
31
+
32
+ context "as millstone :type => :boolean" do
33
+ let(:klass) { MillstoneBooleanModel }
34
+
35
+ it_behaves_like "execute destroy and destroy!"
36
+
37
+ describe "#destroy" do
38
+ before { record.destroy }
39
+ specify { deleted_record.deleted.should be_true }
40
+ end
41
+ end
42
+
43
+ context "as millstone :type => :time" do
44
+ before { Delorean.time_travel_to 1.hour.ago }
45
+ after { Delorean.back_to_the_present }
46
+
47
+ let(:klass) { MillstoneTimeModel }
48
+
49
+ describe "#destroy" do
50
+ before { record.destroy }
51
+ specify { deleted_record.deleted_at.to_s.should == Time.now.to_s }
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ class MillstoneTimeColumn < ActiveRecord::Base
4
+ set_table_name 'time_columns'
5
+ millstone
6
+ end
7
+
8
+ class MillstoneBooleanColumn < ActiveRecord::Base
9
+ set_table_name 'boolean_columns'
10
+ millstone :column => :deleted, :type => :boolean
11
+ end
12
+
13
+ describe Millstone::ActiveRecord::RelationMethods do
14
+ let (:alive_record) { klass.create!(:context => "alive") }
15
+ let (:hidden_record) { klass.create!(:context => "hidden", klass.millstone_column => klass.millstone_generate_column_value) }
16
+
17
+ describe MillstoneTimeColumn do
18
+ let(:klass) { MillstoneTimeColumn }
19
+
20
+ it_should_behave_like "hide soft deletion marked record"
21
+ it_should_behave_like "execute soft deletion" do
22
+ it "should set time to paranoid value" do
23
+ klass.delete(alive_record)
24
+ klass.with_deleted.find(alive_record).deleted_at.should be_a Time
25
+ end
26
+ end
27
+ it_should_behave_like "execute hard deletion"
28
+ it_should_behave_like "check soft deletion"
29
+ end
30
+
31
+ describe MillstoneBooleanColumn do
32
+ let(:klass) { MillstoneBooleanColumn }
33
+
34
+ it_should_behave_like "hide soft deletion marked record"
35
+ it_should_behave_like "execute soft deletion" do
36
+ it "should set true to paranoid value" do
37
+ klass.delete(alive_record)
38
+ klass.with_deleted.find(alive_record).deleted.should be_true
39
+ end
40
+ end
41
+ it_should_behave_like "execute hard deletion"
42
+ it_should_behave_like "check soft deletion"
43
+ end
44
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ class UniquenessWithDeleted < ActiveRecord::Base
4
+ set_table_name 'time_columns'
5
+
6
+ millstone
7
+ validates_uniqueness_of_with_deleted :context
8
+ end
9
+
10
+ class UniquenessWithoutDeleted < ActiveRecord::Base
11
+ set_table_name 'time_columns'
12
+
13
+ millstone
14
+ validates_uniqueness_of :context
15
+ end
16
+
17
+ describe Millstone::ActiveRecord::Validations::UniquenessWithDeletedValidator do
18
+ describe ActiveRecord::Base do
19
+ describe ".validates_uniqueness_of" do
20
+ let(:alive_record) { UniquenessWithoutDeleted.create(:context => "unique1") }
21
+ let(:hidden_record) do
22
+ hidden_record = UniquenessWithoutDeleted.create(:context => "unique2")
23
+ hidden_record.destroy
24
+ hidden_record
25
+ end
26
+
27
+ specify { UniquenessWithoutDeleted.new(:context => alive_record.context).should_not be_valid }
28
+ specify { UniquenessWithoutDeleted.new(:context => hidden_record.context).should be_valid }
29
+ end
30
+
31
+ describe ".validates_uniqueness_of_with_deleted" do
32
+ let(:alive_record) { UniquenessWithDeleted.create(:context => "unique1") }
33
+ let(:hidden_record) do
34
+ hidden_record = UniquenessWithDeleted.create(:context => "unique2")
35
+ hidden_record.destroy
36
+ hidden_record
37
+ end
38
+
39
+ specify { UniquenessWithDeleted.new(:context => alive_record.context).should_not be_valid }
40
+ specify { UniquenessWithDeleted.new(:context => hidden_record.context).should_not be_valid }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rails'
5
+ require 'active_record'
6
+ require 'action_controller'
7
+ require 'action_view'
8
+ require 'delorean'
9
+ require 'millstone'
10
+
11
+ require 'rspec/rails'
12
+
13
+ # Requires supporting files with custom matchers and macros, etc,
14
+ # in ./support/ and its subdirectories.
15
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
16
+
17
+ RSpec.configure do |config|
18
+ config.include Delorean
19
+ config.mock_with :rspec
20
+ config.fixture_path = File.join(File.dirname(__FILE__), 'fixtures')
21
+ config.use_transactional_fixtures = true
22
+ end
23
+
24
+ CreateTestTables.up
25
+
@@ -0,0 +1,6 @@
1
+ shared_examples "check soft deletion" do
2
+ describe "#deleted?" do
3
+ specify { alive_record.should_not be_deleted }
4
+ specify { hidden_record.should be_deleted }
5
+ end
6
+ end
@@ -0,0 +1,43 @@
1
+ shared_examples "delete alive and hidden record" do
2
+ specify "alive record should be deleted from table" do
3
+ expect { klass.with_deleted.find(alive_record) }.to raise_error(ActiveRecord::RecordNotFound)
4
+ end
5
+
6
+ specify "hidden record should be deleted from table" do
7
+ expect { klass.with_deleted.find(hidden_record) }.to raise_error(ActiveRecord::RecordNotFound)
8
+ end
9
+ end
10
+
11
+ shared_examples "execute hard deletion" do
12
+ describe ".delete!" do
13
+ it_behaves_like "delete alive and hidden record" do
14
+ before do
15
+ klass.delete!([alive_record, hidden_record])
16
+ end
17
+ end
18
+ end
19
+
20
+ describe ".delete_all!" do
21
+ it_behaves_like "delete alive and hidden record" do
22
+ before do
23
+ klass.delete_all!(["id IN (?)", [alive_record, hidden_record]])
24
+ end
25
+ end
26
+ end
27
+
28
+ describe ".destroy!" do
29
+ it_behaves_like "delete alive and hidden record" do
30
+ before do
31
+ klass.destroy!([alive_record, hidden_record])
32
+ end
33
+ end
34
+ end
35
+
36
+ describe ".destroy_all!" do
37
+ it_behaves_like "delete alive and hidden record" do
38
+ before do
39
+ klass.destroy_all!(["id IN (?)", [alive_record, hidden_record]])
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,57 @@
1
+ shared_examples "execute soft deletion" do
2
+ describe ".delete_all" do
3
+ it "should mark deletion to alive record" do
4
+ expect do
5
+ klass.delete_all(:id => alive_record)
6
+ end.should change { klass.with_deleted.find(alive_record).millstone_column_value }
7
+ end
8
+
9
+ it "should not mark deletion to hidden record" do
10
+ expect do
11
+ klass.delete_all(:id => hidden_record)
12
+ end.should_not change { klass.with_deleted.find(hidden_record).millstone_column_value }
13
+ end
14
+ end
15
+
16
+ describe ".delete" do
17
+ it "should mark deletion to alive record" do
18
+ expect do
19
+ klass.delete(alive_record)
20
+ end.should change { klass.with_deleted.find(alive_record).millstone_column_value }
21
+ end
22
+
23
+ it "should not mark deletion to hidden record" do
24
+ expect do
25
+ klass.delete(hidden_record)
26
+ end.should_not change { klass.with_deleted.find(hidden_record).millstone_column_value }
27
+ end
28
+ end
29
+
30
+ describe ".destroy_all" do
31
+ it "should mark deletion to alive record" do
32
+ expect do
33
+ klass.destroy_all(:id => alive_record)
34
+ end.should change { klass.with_deleted.find(alive_record).millstone_column_value }
35
+ end
36
+
37
+ it "should not mark deletion to hidden record" do
38
+ expect do
39
+ klass.destroy_all(:id => hidden_record)
40
+ end.should_not change { klass.with_deleted.find(hidden_record).millstone_column_value }
41
+ end
42
+ end
43
+
44
+ describe ".destroy" do
45
+ it "should mark deletion to alive record" do
46
+ expect do
47
+ klass.destroy(alive_record)
48
+ end.should change { klass.with_deleted.find(alive_record).millstone_column_value }
49
+ end
50
+
51
+ it "should not mark deletion to hidden record" do
52
+ expect do
53
+ klass.destroy(hidden_record)
54
+ end.should raise_error(ActiveRecord::RecordNotFound)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,98 @@
1
+ shared_examples "hide soft deletion marked record" do
2
+ before do
3
+ klass.delete_all
4
+ 3.times { klass.create!(:context => "alive") }
5
+ 2.times { klass.create!(:context => "hidden", klass.millstone_column => klass.millstone_generate_column_value) }
6
+ end
7
+
8
+ describe ".all" do
9
+ subject { klass.all }
10
+ it { should_not include hidden_record }
11
+ it { should include alive_record }
12
+ end
13
+
14
+ describe ".find" do
15
+ specify { klass.find(alive_record).should_not be_nil }
16
+
17
+ specify do
18
+ expect { klass.find(hidden_record) }.to raise_error(ActiveRecord::RecordNotFound)
19
+ end
20
+
21
+ context "options :with_deleted" do
22
+ specify { klass.find(hidden_record, :with_deleted => true).should_not be_nil }
23
+ specify { klass.find(alive_record, :with_deleted => true).should_not be_nil }
24
+ end
25
+
26
+ context "options :only_deleted" do
27
+ specify { klass.find(hidden_record, :only_deleted => true).should_not be_nil }
28
+
29
+ specify do
30
+ expect { klass.find(alive_record, :only_deleted => true) }.to raise_error(ActiveRecord::RecordNotFound)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe ".count" do
36
+ subject { klass.count }
37
+ it "should return record count without hidden record" do
38
+ should == 3
39
+ end
40
+ end
41
+
42
+ describe ".with_deleted" do
43
+ describe ".all" do
44
+ subject { klass.with_deleted.all }
45
+ it { should include hidden_record }
46
+ it { should include alive_record }
47
+ end
48
+
49
+ describe ".find" do
50
+ context "when specify hidden record" do
51
+ subject { klass.only_deleted.find(hidden_record) }
52
+ it { should eq hidden_record }
53
+ end
54
+
55
+ context "when specify alive record" do
56
+ subject { klass.find(alive_record) }
57
+ it { should eq alive_record }
58
+ end
59
+ end
60
+
61
+ describe ".count" do
62
+ subject { klass.with_deleted.count }
63
+ it "should return all record count" do
64
+ should == 5
65
+ end
66
+ end
67
+ end
68
+
69
+ describe ".only_deleted" do
70
+ describe ".all" do
71
+ subject { klass.only_deleted.all }
72
+ it { should include hidden_record }
73
+ it { should_not include alive_record }
74
+ end
75
+
76
+ describe ".find" do
77
+ context "when specify hidden record" do
78
+ subject { klass.only_deleted.find(hidden_record) }
79
+ it { should eq hidden_record }
80
+ end
81
+
82
+ context "when specify alive record" do
83
+ it "should raise error ActiveRecord::RecordNotFound" do
84
+ expect do
85
+ klass.only_deleted.find(alive_record)
86
+ end.to raise_error(ActiveRecord::RecordNotFound)
87
+ end
88
+ end
89
+ end
90
+
91
+ describe ".count" do
92
+ subject { klass.only_deleted.count }
93
+ it "should return only hidden record count" do
94
+ should == 2
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,49 @@
1
+ require 'active_record'
2
+
3
+ # database connection
4
+ ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}}
5
+ ActiveRecord::Base.establish_connection('test')
6
+
7
+ class CreateTestTables < ActiveRecord::Migration
8
+ def self.up
9
+ create_table :time_columns, :force => true do |t|
10
+ t.string :context
11
+ t.datetime :deleted_at
12
+ t.timestamps
13
+ end
14
+
15
+ create_table :boolean_columns, :force => true do |t|
16
+ t.string :context
17
+ t.boolean :deleted
18
+ t.timestamps
19
+ end
20
+
21
+ create_table :children, :force => true do |t|
22
+ t.integer :parent_id
23
+ t.string :context
24
+ t.datetime :deleted_at
25
+ t.timestamps
26
+ end
27
+
28
+ create_table :polymorphic_children, :force => true do |t|
29
+ t.string :polymorphous_type
30
+ t.integer :polymorphous_id
31
+ t.string :context
32
+ t.datetime :deleted_at
33
+ t.timestamps
34
+ end
35
+
36
+ create_table :masters, :force => true do |t|
37
+ t.string :context
38
+ t.timestamps
39
+ end
40
+
41
+ create_table :havings, :force => true do |t|
42
+ t.integer :parent_id
43
+ t.integer :master_id
44
+ t.datetime :deleted_at
45
+ t.timestamps
46
+ end
47
+
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: millstone
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Yoshikazu Ozawa
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-09 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 11
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 6
34
+ version: 3.0.6
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: bundler
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 23
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 0
50
+ version: 1.0.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: sqlite3
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: rspec
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 15
76
+ segments:
77
+ - 2
78
+ - 0
79
+ - 0
80
+ version: 2.0.0
81
+ type: :development
82
+ version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-rails
85
+ prerelease: false
86
+ requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 15
92
+ segments:
93
+ - 2
94
+ - 0
95
+ - 0
96
+ version: 2.0.0
97
+ type: :development
98
+ version_requirements: *id005
99
+ - !ruby/object:Gem::Dependency
100
+ name: delorean
101
+ prerelease: false
102
+ requirement: &id006 !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 3
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ type: :development
112
+ version_requirements: *id006
113
+ description: ActiveRecord plugin which allows you to hide without actually deleting them for Rails3. Millstone is extending ActiveRecord::Relation
114
+ email:
115
+ - yoshikazu.ozawa@gmail.com
116
+ executables: []
117
+
118
+ extensions: []
119
+
120
+ extra_rdoc_files: []
121
+
122
+ files:
123
+ - .gitignore
124
+ - .rspec
125
+ - Gemfile
126
+ - LICENSE
127
+ - README.md
128
+ - Rakefile
129
+ - lib/millstone.rb
130
+ - lib/millstone/active_record/associations.rb
131
+ - lib/millstone/active_record/associations/belongs_to_association.rb
132
+ - lib/millstone/active_record/associations/belongs_to_polymorphic_association.rb
133
+ - lib/millstone/active_record/associations/has_many_through_without_deleted_association.rb
134
+ - lib/millstone/active_record/extension.rb
135
+ - lib/millstone/active_record/relation_methods.rb
136
+ - lib/millstone/active_record/validations/uniqueness_with_deleted.rb
137
+ - millstone.gemspec
138
+ - spec/models/associations/belongs_to_association_spec.rb
139
+ - spec/models/associations/belongs_to_polymorphic_association_spec.rb
140
+ - spec/models/associations/has_many_through_without_deleted_association_spec.rb
141
+ - spec/models/extension_spec.rb
142
+ - spec/models/relation_methods_spec.rb
143
+ - spec/models/validations/uniqueness_with_deleted_spec.rb
144
+ - spec/spec_helper.rb
145
+ - spec/support/examples/check_soft_deletion.rb
146
+ - spec/support/examples/execute_hard_deletion.rb
147
+ - spec/support/examples/execute_soft_deletion.rb
148
+ - spec/support/examples/hide_soft_deletion_marked_record.rb
149
+ - spec/support/migration.rb
150
+ has_rdoc: true
151
+ homepage: https://github.com/relax4u/millstone
152
+ licenses:
153
+ - MIT
154
+ post_install_message:
155
+ rdoc_options: []
156
+
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ hash: 3
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ hash: 3
174
+ segments:
175
+ - 0
176
+ version: "0"
177
+ requirements: []
178
+
179
+ rubyforge_project:
180
+ rubygems_version: 1.3.7
181
+ signing_key:
182
+ specification_version: 3
183
+ summary: ActiveRecord plugin which allows you to hide without actually deleting them for Rails3.
184
+ test_files:
185
+ - spec/models/associations/belongs_to_association_spec.rb
186
+ - spec/models/associations/belongs_to_polymorphic_association_spec.rb
187
+ - spec/models/associations/has_many_through_without_deleted_association_spec.rb
188
+ - spec/models/extension_spec.rb
189
+ - spec/models/relation_methods_spec.rb
190
+ - spec/models/validations/uniqueness_with_deleted_spec.rb
191
+ - spec/spec_helper.rb
192
+ - spec/support/examples/check_soft_deletion.rb
193
+ - spec/support/examples/execute_hard_deletion.rb
194
+ - spec/support/examples/execute_soft_deletion.rb
195
+ - spec/support/examples/hide_soft_deletion_marked_record.rb
196
+ - spec/support/migration.rb