draftsman 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +3 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +3 -0
  8. data/Gemfile.lock +97 -0
  9. data/LICENSE +20 -0
  10. data/README.md +506 -0
  11. data/Rakefile +6 -0
  12. data/draftsman.gemspec +33 -0
  13. data/lib/draftsman/config.rb +13 -0
  14. data/lib/draftsman/draft.rb +289 -0
  15. data/lib/draftsman/frameworks/cucumber.rb +7 -0
  16. data/lib/draftsman/frameworks/rails.rb +58 -0
  17. data/lib/draftsman/frameworks/rspec.rb +16 -0
  18. data/lib/draftsman/frameworks/sinatra.rb +31 -0
  19. data/lib/draftsman/model.rb +428 -0
  20. data/lib/draftsman/serializers/json.rb +17 -0
  21. data/lib/draftsman/serializers/yaml.rb +17 -0
  22. data/lib/draftsman/version.rb +3 -0
  23. data/lib/draftsman.rb +101 -0
  24. data/lib/generators/draftsman/install_generator.rb +27 -0
  25. data/lib/generators/draftsman/templates/add_object_changes_column_to_drafts.rb +9 -0
  26. data/lib/generators/draftsman/templates/config/initializers/draftsman.rb +11 -0
  27. data/lib/generators/draftsman/templates/create_drafts.rb +22 -0
  28. data/spec/controllers/informants_controller_spec.rb +27 -0
  29. data/spec/controllers/users_controller_spec.rb +23 -0
  30. data/spec/controllers/whodunnits_controller_spec.rb +24 -0
  31. data/spec/draftsman_spec.rb +19 -0
  32. data/spec/dummy/Rakefile +7 -0
  33. data/spec/dummy/app/assets/images/rails.png +0 -0
  34. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  35. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  36. data/spec/dummy/app/controllers/application_controller.rb +20 -0
  37. data/spec/dummy/app/controllers/informants_controller.rb +8 -0
  38. data/spec/dummy/app/controllers/users_controller.rb +8 -0
  39. data/spec/dummy/app/controllers/whodunnits_controller.rb +8 -0
  40. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  41. data/spec/dummy/app/helpers/messages_helper.rb +2 -0
  42. data/spec/dummy/app/mailers/.gitkeep +0 -0
  43. data/spec/dummy/app/models/bastard.rb +3 -0
  44. data/spec/dummy/app/models/child.rb +4 -0
  45. data/spec/dummy/app/models/parent.rb +5 -0
  46. data/spec/dummy/app/models/trashable.rb +3 -0
  47. data/spec/dummy/app/models/vanilla.rb +3 -0
  48. data/spec/dummy/app/models/whitelister.rb +3 -0
  49. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  50. data/spec/dummy/config/application.rb +37 -0
  51. data/spec/dummy/config/boot.rb +6 -0
  52. data/spec/dummy/config/database.yml +25 -0
  53. data/spec/dummy/config/environment.rb +5 -0
  54. data/spec/dummy/config/environments/development.rb +32 -0
  55. data/spec/dummy/config/environments/production.rb +73 -0
  56. data/spec/dummy/config/environments/test.rb +39 -0
  57. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  58. data/spec/dummy/config/initializers/inflections.rb +15 -0
  59. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  60. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  61. data/spec/dummy/config/initializers/session_store.rb +8 -0
  62. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  63. data/spec/dummy/config/locales/en.yml +5 -0
  64. data/spec/dummy/config/routes.rb +6 -0
  65. data/spec/dummy/config.ru +4 -0
  66. data/spec/dummy/db/migrate/20110208155312_set_up_test_tables.rb +86 -0
  67. data/spec/dummy/db/schema.rb +106 -0
  68. data/spec/dummy/db/seeds.rb +7 -0
  69. data/spec/dummy/lib/assets/.gitkeep +0 -0
  70. data/spec/dummy/lib/tasks/.gitkeep +0 -0
  71. data/spec/dummy/log/.gitkeep +0 -0
  72. data/spec/dummy/public/404.html +26 -0
  73. data/spec/dummy/public/422.html +26 -0
  74. data/spec/dummy/public/500.html +25 -0
  75. data/spec/dummy/public/favicon.ico +0 -0
  76. data/spec/dummy/script/rails +6 -0
  77. data/spec/models/child_spec.rb +205 -0
  78. data/spec/models/draft_spec.rb +297 -0
  79. data/spec/models/parent_spec.rb +191 -0
  80. data/spec/models/trashable_spec.rb +164 -0
  81. data/spec/models/vanilla_spec.rb +201 -0
  82. data/spec/models/whitelister_spec.rb +262 -0
  83. data/spec/spec_helper.rb +52 -0
  84. metadata +304 -0
@@ -0,0 +1,297 @@
1
+ require 'spec_helper'
2
+
3
+ describe Draftsman::Draft do
4
+ let(:trashable) { Trashable.new :name => 'Bob' }
5
+ subject { trashable.draft }
6
+
7
+ describe :event, :create?, :update?, :destroy?, :object, :changeset do
8
+ context 'with `create` draft' do
9
+ before { trashable.draft_creation }
10
+ its(:event) { should eql 'create' }
11
+ its(:create?) { should be_true }
12
+ its(:update?) { should be_false }
13
+ its(:destroy?) { should be_false }
14
+ its(:object) { should be_present }
15
+ its(:changeset) { should include :id }
16
+ its(:changeset) { should include :name }
17
+ its(:changeset) { should_not include :title }
18
+ its(:changeset) { should include :created_at }
19
+ its(:changeset) { should include :updated_at }
20
+ its(:previous_draft) { should be_nil }
21
+
22
+ context 'updated create' do
23
+ before do
24
+ trashable.name = 'Sam'
25
+ trashable.draft_update
26
+ end
27
+
28
+ it { should be_create }
29
+ it { should_not be_update }
30
+ it { should_not be_destroy }
31
+ its(:event) { should eql 'create' }
32
+ its(:object) { should be_present }
33
+ its(:changeset) { should include :id }
34
+ its(:changeset) { should include :name }
35
+ its(:changeset) { should_not include :title }
36
+ its(:changeset) { should include :created_at }
37
+ its(:changeset) { should include :updated_at }
38
+ its(:previous_draft) { should be_nil }
39
+ end
40
+ end
41
+
42
+ context 'with `update` draft' do
43
+ before do
44
+ trashable.save!
45
+ trashable.name = 'Sam'
46
+ trashable.title = 'My Title'
47
+ trashable.draft_update
48
+ end
49
+
50
+ it { should_not be_create }
51
+ it { should be_update }
52
+ it { should_not be_destroy }
53
+ its(:event) { should eql 'update' }
54
+ its(:object) { should be_present }
55
+ its(:changeset) { should_not include :id }
56
+ its(:changeset) { should include :name }
57
+ its(:changeset) { should include :title }
58
+ its(:changeset) { should_not include :created_at }
59
+ its(:changeset) { should_not include :updated_at }
60
+ its(:previous_draft) { should be_nil }
61
+
62
+ context 'updating the update' do
63
+ before do
64
+ trashable.title = nil
65
+ trashable.draft_update
66
+ end
67
+
68
+ it { should_not be_create }
69
+ it { should be_update }
70
+ it { should_not be_destroy }
71
+ its(:event) { should eql 'update' }
72
+ its(:object) { should be_present }
73
+ its(:changeset) { should_not include :id }
74
+ its(:changeset) { should include :name }
75
+ its(:changeset) { should_not include :title }
76
+ its(:changeset) { should_not include :created_at }
77
+ its(:changeset) { should_not include :updated_at }
78
+ its(:previous_draft) { should be_nil }
79
+ end
80
+ end
81
+
82
+ context 'with `destroy` draft' do
83
+ context 'without previous draft' do
84
+ before do
85
+ trashable.save!
86
+ trashable.draft_destroy
87
+ end
88
+
89
+ it { should_not be_create }
90
+ it { should_not be_update }
91
+ it { should be_destroy }
92
+ it { should_not be_destroyed }
93
+ its(:event) { should eql 'destroy' }
94
+ its(:object) { should be_present }
95
+ its(:changeset) { should eql Hash.new }
96
+ its(:previous_draft) { should be_nil }
97
+ end
98
+
99
+ context 'with previous `create` draft' do
100
+ before do
101
+ trashable.draft_creation
102
+ trashable.draft_destroy
103
+ end
104
+
105
+ it { should_not be_create }
106
+ it { should_not be_update }
107
+ it { should be_destroy }
108
+ it { should_not be_destroyed }
109
+ its(:event) { should eql 'destroy' }
110
+ its(:object) { should be_present }
111
+ its(:changeset) { should include :id }
112
+ its(:changeset) { should include :name }
113
+ its(:changeset) { should_not include :title }
114
+ its(:changeset) { should include :created_at }
115
+ its(:changeset) { should include :updated_at }
116
+ its(:previous_draft) { should be_present }
117
+ end
118
+ end
119
+ end
120
+
121
+ describe :publish! do
122
+ context 'with `create` draft' do
123
+ before { trashable.draft_creation }
124
+ subject { trashable.draft.publish!; return trashable.reload }
125
+ it { expect { subject }.to_not raise_exception }
126
+ it { should be_published }
127
+ it { should_not be_trashed }
128
+ it { should_not be_draft }
129
+ its(:published_at) { should be_present }
130
+ its(:draft_id) { should be_nil }
131
+ its(:draft) { should be_nil }
132
+ its(:trashed_at) { should be_nil }
133
+
134
+ it 'deletes the draft' do
135
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
136
+ end
137
+ end
138
+
139
+ context 'with `update` draft' do
140
+ before do
141
+ trashable.save!
142
+ trashable.name = 'Sam'
143
+ trashable.draft_update
144
+ end
145
+
146
+ subject { trashable.draft.publish!; return trashable.reload }
147
+ it { expect { subject }.to_not raise_exception }
148
+ it { should be_published }
149
+ it { should_not be_draft }
150
+ it { should_not be_trashed }
151
+ its(:name) { should eql 'Sam' }
152
+ its(:published_at) { should be_present }
153
+ its(:draft_id) { should be_nil }
154
+ its(:draft) { should be_nil }
155
+ its(:trashed_at) { should be_nil }
156
+
157
+ it 'deletes the draft' do
158
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
159
+ end
160
+
161
+ it 'does not delete the associated item' do
162
+ expect { subject }.to_not change(Trashable, :count)
163
+ end
164
+ end
165
+
166
+ context 'with `destroy` draft' do
167
+ context 'without previous draft' do
168
+ before do
169
+ trashable.save!
170
+ trashable.draft_destroy
171
+ end
172
+
173
+ subject { trashable.draft.publish! }
174
+
175
+ it 'destroys the draft' do
176
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
177
+ end
178
+
179
+ it 'deletes the associated item' do
180
+ expect { subject }.to change(Trashable, :count).by(-1)
181
+ end
182
+ end
183
+
184
+ context 'with previous `create` draft' do
185
+ before do
186
+ trashable.draft_creation
187
+ trashable.draft_destroy
188
+ end
189
+
190
+ subject { trashable.draft.publish! }
191
+
192
+ it 'destroys the draft' do
193
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
194
+ end
195
+
196
+ it 'deletes the associated item' do
197
+ expect { subject }.to change(Trashable, :count).by(-1)
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ describe :revert! do
204
+ context 'with `create` draft' do
205
+ before { trashable.draft_creation }
206
+ subject { trashable.draft.revert! }
207
+ it { expect { subject }.to_not raise_exception }
208
+
209
+ it 'deletes the draft' do
210
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
211
+ end
212
+
213
+ it 'deletes associated item' do
214
+ expect { subject }.to change(Trashable, :count).by(-1)
215
+ end
216
+ end
217
+
218
+ context 'with `update` draft' do
219
+ before do
220
+ trashable.save!
221
+ trashable.name = 'Sam'
222
+ trashable.draft_update
223
+ end
224
+
225
+ subject { trashable.draft.revert!; return trashable.reload }
226
+ it { expect { subject }.to_not raise_exception }
227
+ it { should_not be_draft }
228
+ its(:name) { should eql 'Bob' }
229
+ its(:draft_id) { should be_nil }
230
+ its(:draft) { should be_nil }
231
+
232
+ it 'deletes the draft' do
233
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
234
+ end
235
+
236
+ it 'does not delete the associated item' do
237
+ expect { subject }.to_not change(Trashable, :count)
238
+ end
239
+ end
240
+
241
+ context 'with `destroy` draft' do
242
+ context 'without previous draft' do
243
+ before do
244
+ trashable.save!
245
+ trashable.draft_destroy
246
+ end
247
+
248
+ subject { trashable.draft.revert!; return trashable.reload }
249
+ it { expect { subject }.to_not raise_exception }
250
+ it { should_not be_trashed }
251
+ it { should_not be_draft }
252
+ its(:draft_id) { should be_nil }
253
+ its(:draft) { should be_nil }
254
+ its(:trashed_at) { should be_nil }
255
+
256
+ it 'deletes the draft' do
257
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
258
+ end
259
+
260
+ it 'does not delete the associated item' do
261
+ expect { subject }.to_not change(Trashable, :count)
262
+ end
263
+ end
264
+
265
+ context 'with previous `create` draft' do
266
+ before do
267
+ trashable.draft_creation
268
+ trashable.draft_destroy
269
+ end
270
+
271
+ subject { trashable.draft.revert!; return trashable.reload }
272
+ it { expect { subject }.to_not raise_exception }
273
+ it { should_not be_trashed }
274
+ it { should be_draft }
275
+ its(:draft_id) { should be_present }
276
+ its(:draft) { should be_present }
277
+ its(:trashed_at) { should be_nil }
278
+
279
+ it 'deletes the `destroy` draft' do
280
+ expect { subject }.to change(Draftsman::Draft.where(:event => 'destroy'), :count).by(-1)
281
+ end
282
+
283
+ it 'reifies the previous `create` draft' do
284
+ expect { subject }.to change(Draftsman::Draft.where(:event => 'create'), :count).by(1)
285
+ end
286
+
287
+ it 'does not delete the associated item' do
288
+ expect { subject }.to_not change(Trashable, :count)
289
+ end
290
+
291
+ its "draft's previous draft should be nil" do
292
+ subject.draft.previous_draft.should be_nil
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,191 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parent do
4
+ let(:parent) { Parent.new(:name => 'Marge') }
5
+ let(:child) { Child.new(:name => 'Lisa', :parent => parent) }
6
+
7
+ describe :publish! do
8
+ context 'parent `create` draft with child `create` draft' do
9
+ before do
10
+ parent.draft_creation
11
+ child.draft_creation
12
+ end
13
+
14
+ subject { parent.draft.publish! }
15
+
16
+ its 'parent should be published' do
17
+ subject
18
+ parent.reload.should be_published
19
+ end
20
+
21
+ its 'parent should not be a draft' do
22
+ subject
23
+ parent.reload.should_not be_draft
24
+ end
25
+
26
+ its 'child should be a draft' do
27
+ subject
28
+ child.reload.should be_draft
29
+ end
30
+
31
+ its 'child should not be published' do
32
+ subject
33
+ child.reload.should_not be_published
34
+ end
35
+
36
+ it 'destroys 1 draft' do
37
+ expect { subject }.to change(Draftsman::Draft, :count).by(-1)
38
+ end
39
+
40
+ it "destroys the parent's draft" do
41
+ expect { subject }.to change(Draftsman::Draft.where(:item_type => 'Parent'), :count).by(-1)
42
+ end
43
+ end
44
+
45
+ context 'parent `destroy` draft with child `destroy` draft' do
46
+ before do
47
+ child.save!
48
+ child.draft_destroy
49
+ parent.draft_destroy
50
+ end
51
+
52
+ subject { parent.draft.publish! }
53
+
54
+ it 'destroys the parent' do
55
+ expect { subject }.to change(Parent, :count).by(-1)
56
+ end
57
+
58
+ it 'destroys the child' do
59
+ expect { subject }.to change(Child, :count).by(-1)
60
+ end
61
+
62
+ it 'destroys 2 drafts' do
63
+ expect { subject }.to change(Draftsman::Draft, :count).by(-2)
64
+ end
65
+ end
66
+ end
67
+
68
+ describe :revert! do
69
+ context 'parent `create` draft with child `create` draft' do
70
+ before do
71
+ parent.draft_creation
72
+ child.draft_creation
73
+ end
74
+
75
+ subject { parent.draft.revert! }
76
+
77
+ it 'destroys the parent' do
78
+ expect { subject }.to change(Parent, :count).by(-1)
79
+ end
80
+
81
+ it 'destroys the child' do
82
+ expect { subject }.to change(Child, :count).by(-1)
83
+ end
84
+
85
+ it 'destroys both drafts' do
86
+ expect { subject }.to change(Draftsman::Draft, :count).by(-2)
87
+ end
88
+ end
89
+
90
+ context 'parent `destroy` draft with child `destroy` draft' do
91
+ before do
92
+ child.save!
93
+ child.draft_destroy
94
+ parent.draft_destroy
95
+ end
96
+
97
+ subject do
98
+ parent.draft.revert!
99
+ child.reload
100
+ parent.reload
101
+ end
102
+
103
+ it { should be_persisted }
104
+ it { should_not be_draft }
105
+ it { should_not be_trashed }
106
+
107
+ it "keeps the child's draft" do
108
+ expect { subject }.to_not change(Draftsman::Draft.where(:item_type => 'Child'), :count)
109
+ end
110
+
111
+ it "deletes the parent's draft" do
112
+ expect { subject }.to change(Draftsman::Draft.where(:item_type => 'Parent'), :count).by(-1)
113
+ end
114
+
115
+ its 'child should remain a draft' do
116
+ subject
117
+ child.should be_draft
118
+ end
119
+
120
+ its 'child should still be a `destroy` draft' do
121
+ subject
122
+ child.draft.reload.should be_destroy
123
+ end
124
+
125
+ its 'child should still be trashed' do
126
+ subject
127
+ child.should be_trashed
128
+ end
129
+ end
130
+ end
131
+
132
+ describe :draft_publication_dependencies do
133
+ context 'parent `create` draft with child `create` draft' do
134
+ before do
135
+ parent.draft_creation
136
+ child.draft_creation
137
+ end
138
+
139
+ subject { parent.draft }
140
+ its(:draft_publication_dependencies) { should be_empty }
141
+ end
142
+
143
+ context 'parent `update` draft with child `create` draft' do
144
+ before do
145
+ parent.save!
146
+ parent.name = 'Selma'
147
+ parent.draft_update
148
+ child.draft_creation
149
+ end
150
+
151
+ subject { parent.draft }
152
+ its(:draft_publication_dependencies) { should be_empty }
153
+ end
154
+
155
+ context 'parent `destroy` draft with child `destroy` draft' do
156
+ before do
157
+ child.save!
158
+ parent.draft_destroy
159
+ child.reload
160
+ end
161
+
162
+ subject { parent.draft }
163
+ its(:draft_publication_dependencies) { should be_present }
164
+ its(:draft_publication_dependencies) { should include child.draft }
165
+ end
166
+ end
167
+
168
+ describe :draft_reversion_dependencies do
169
+ context 'parent `create` draft with child `create` draft' do
170
+ before do
171
+ parent.draft_creation
172
+ child.draft_creation
173
+ end
174
+
175
+ subject { parent.draft }
176
+ its(:draft_reversion_dependencies) { should be_present }
177
+ its(:draft_reversion_dependencies) { should include child.draft }
178
+ end
179
+
180
+ context 'parent `destroy` draft with child `destroy` draft' do
181
+ before do
182
+ child.save!
183
+ parent.draft_destroy
184
+ child.reload
185
+ end
186
+
187
+ subject { parent.draft }
188
+ its(:draft_reversion_dependencies) { should be_empty }
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ # A Trashable has a simple call to `has_drafts` without any options specified. The model also contains a `deleted_at`
4
+ # attribute, which allows deletes to be drafts too.
5
+ describe Trashable do
6
+ let(:trashable) { Trashable.new :name => 'Bob' }
7
+ it { should be_draftable }
8
+
9
+ # Not affected by this customization
10
+ describe :draft_creation do
11
+ end
12
+
13
+ # Not affected by this customization
14
+ describe :draft_update do
15
+ end
16
+
17
+ describe :draft_destroy do
18
+ context 'with `:create` draft' do
19
+ before { trashable.draft_creation }
20
+ subject { trashable.draft_destroy; return trashable }
21
+ it { should be_persisted }
22
+ it { should_not be_published }
23
+ it { should be_draft }
24
+ it { should be_trashed}
25
+ its(:published_at) { should be_nil }
26
+ its(:trashed_at) { should be_present }
27
+ its(:draft_id) { should be_present }
28
+ its(:draft) { should be_present }
29
+ its(:draft) { should be_destroy }
30
+ its(:name) { should eql 'Bob' }
31
+
32
+ it 'keeps the item' do
33
+ expect { subject }.to_not change(Trashable, :count)
34
+ end
35
+
36
+ it 'keeps the associated draft' do
37
+ expect { subject }.to_not change(Draftsman::Draft.where(:id => trashable.draft_id), :count)
38
+ end
39
+
40
+ its "draft's name should be 'Bob'" do
41
+ subject.draft.reify.name.should eql 'Bob'
42
+ end
43
+ end
44
+
45
+ context 'with `:update` draft' do
46
+ before do
47
+ trashable.save!
48
+ trashable.published_at = Time.now
49
+ trashable.save!
50
+ trashable.name = 'Sam'
51
+ trashable.draft_update
52
+ end
53
+
54
+ subject { trashable.draft_destroy; return trashable.reload }
55
+ it { should be_persisted }
56
+ it { should be_published }
57
+ it { should be_draft }
58
+ it { should be_trashed}
59
+ its(:published_at) { should be_present }
60
+ its(:trashed_at) { should be_present }
61
+ its(:draft_id) { should be_present }
62
+ its(:draft) { should be_present }
63
+ its(:draft) { should be_destroy }
64
+ its(:name) { should eql 'Bob' }
65
+
66
+ it 'keeps the item' do
67
+ expect { subject }.to_not change(Trashable, :count)
68
+ end
69
+
70
+ it 'keeps the associated draft' do
71
+ expect { subject }.to_not change(Draftsman::Draft.where(:id => trashable.draft_id), :count)
72
+ end
73
+
74
+ its "draft's name should be 'Sam'" do
75
+ subject.draft.reify.name.should eql 'Sam'
76
+ end
77
+ end
78
+
79
+ context 'without draft' do
80
+ before do
81
+ trashable.save!
82
+ trashable.update_attributes! :published_at => Time.now
83
+ end
84
+
85
+ subject { trashable.draft_destroy; return trashable.reload }
86
+ it { should be_persisted }
87
+ it { should be_published }
88
+ it { should be_draft }
89
+ it { should be_trashed }
90
+ its(:published_at) { should be_present }
91
+ its(:trashed_at) { should be_present }
92
+ its(:draft_id) { should be_present }
93
+ its(:draft) { should be_present }
94
+ its(:draft) { should be_destroy }
95
+ its(:name) { should eql 'Bob' }
96
+
97
+ it 'keeps the item' do
98
+ expect { subject }.to_not change(Trashable, :count)
99
+ end
100
+
101
+ it 'creates a draft' do
102
+ expect { subject }.to change(Draftsman::Draft, :count).by(1)
103
+ end
104
+ end
105
+ end
106
+
107
+ describe 'scopes' do
108
+ let!(:drafted_trashable) { trashable.draft_creation; return trashable }
109
+ let!(:published_trashable) { Trashable.create :name => 'Jane', :published_at => Time.now }
110
+ let!(:trashed_trashable) { Trashable.create :name => 'Ralph' }
111
+
112
+ # Not affected by this customization
113
+ describe :drafted do
114
+ end
115
+
116
+ describe :live do
117
+ before { trashed_trashable.draft_destroy }
118
+ subject { Trashable.live }
119
+ its(:count) { should eql 2 }
120
+
121
+ it 'does not raise an exception' do
122
+ expect { subject }.to_not raise_exception
123
+ end
124
+
125
+ it 'includes the drafted item' do
126
+ subject.should include drafted_trashable
127
+ end
128
+
129
+ it 'includes the published item' do
130
+ subject.should include published_trashable
131
+ end
132
+
133
+ it 'does not include the trashed item' do
134
+ subject.should_not include trashed_trashable
135
+ end
136
+ end
137
+
138
+ # Not affected by this customization
139
+ describe :published do
140
+ end
141
+
142
+ describe :trashed do
143
+ before { trashed_trashable.draft_destroy }
144
+ subject { Trashable.trashed }
145
+ its(:count) { should eql 1 }
146
+
147
+ it 'does not raise an exception' do
148
+ expect { subject.load }.to_not raise_exception
149
+ end
150
+
151
+ it 'does not include the drafted item' do
152
+ subject.should_not include drafted_trashable
153
+ end
154
+
155
+ it 'does not include the published item' do
156
+ subject.should_not include published_trashable
157
+ end
158
+
159
+ it 'includes the trashed item' do
160
+ subject.should include trashed_trashable
161
+ end
162
+ end
163
+ end
164
+ end