mongo_mapper 0.13.0 → 0.15.1

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.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.md +61 -0
  4. data/examples/keys.rb +1 -1
  5. data/examples/modifiers/set.rb +1 -1
  6. data/examples/querying.rb +1 -1
  7. data/examples/safe.rb +2 -2
  8. data/examples/scopes.rb +1 -1
  9. data/lib/mongo_mapper.rb +7 -0
  10. data/lib/mongo_mapper/connection.rb +16 -37
  11. data/lib/mongo_mapper/document.rb +4 -0
  12. data/lib/mongo_mapper/extensions/array.rb +14 -6
  13. data/lib/mongo_mapper/extensions/hash.rb +15 -3
  14. data/lib/mongo_mapper/extensions/object.rb +4 -0
  15. data/lib/mongo_mapper/extensions/object_id.rb +5 -1
  16. data/lib/mongo_mapper/extensions/string.rb +13 -5
  17. data/lib/mongo_mapper/extensions/symbol.rb +18 -0
  18. data/lib/mongo_mapper/plugins/accessible.rb +15 -5
  19. data/lib/mongo_mapper/plugins/associations.rb +7 -6
  20. data/lib/mongo_mapper/plugins/associations/base.rb +27 -14
  21. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +10 -1
  22. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +9 -8
  23. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +12 -11
  24. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +4 -4
  25. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +60 -29
  26. data/lib/mongo_mapper/plugins/associations/in_foreign_array_proxy.rb +136 -0
  27. data/lib/mongo_mapper/plugins/associations/many_association.rb +4 -2
  28. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +18 -16
  29. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +55 -48
  30. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +14 -13
  31. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +7 -6
  32. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +7 -5
  33. data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +14 -11
  34. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +14 -13
  35. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +9 -9
  36. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +27 -26
  37. data/lib/mongo_mapper/plugins/associations/proxy.rb +36 -29
  38. data/lib/mongo_mapper/plugins/associations/single_association.rb +5 -4
  39. data/lib/mongo_mapper/plugins/callbacks.rb +13 -0
  40. data/lib/mongo_mapper/plugins/counter_cache.rb +97 -0
  41. data/lib/mongo_mapper/plugins/dirty.rb +29 -37
  42. data/lib/mongo_mapper/plugins/document.rb +1 -1
  43. data/lib/mongo_mapper/plugins/dynamic_querying.rb +10 -9
  44. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +18 -17
  45. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +2 -1
  46. data/lib/mongo_mapper/plugins/embedded_document.rb +1 -1
  47. data/lib/mongo_mapper/plugins/identity_map.rb +4 -2
  48. data/lib/mongo_mapper/plugins/indexes.rb +14 -7
  49. data/lib/mongo_mapper/plugins/keys.rb +170 -151
  50. data/lib/mongo_mapper/plugins/keys/key.rb +27 -16
  51. data/lib/mongo_mapper/plugins/keys/static.rb +45 -0
  52. data/lib/mongo_mapper/plugins/modifiers.rb +64 -38
  53. data/lib/mongo_mapper/plugins/partial_updates.rb +86 -0
  54. data/lib/mongo_mapper/plugins/persistence.rb +13 -8
  55. data/lib/mongo_mapper/plugins/protected.rb +6 -5
  56. data/lib/mongo_mapper/plugins/querying.rb +85 -42
  57. data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +20 -15
  58. data/lib/mongo_mapper/plugins/rails.rb +1 -0
  59. data/lib/mongo_mapper/plugins/safe.rb +10 -4
  60. data/lib/mongo_mapper/plugins/sci.rb +0 -0
  61. data/lib/mongo_mapper/plugins/scopes.rb +78 -7
  62. data/lib/mongo_mapper/plugins/stats.rb +17 -0
  63. data/lib/mongo_mapper/plugins/strong_parameters.rb +26 -0
  64. data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
  65. data/lib/mongo_mapper/plugins/validations.rb +1 -1
  66. data/lib/mongo_mapper/railtie.rb +4 -3
  67. data/lib/mongo_mapper/utils.rb +2 -2
  68. data/lib/mongo_mapper/version.rb +1 -1
  69. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +12 -13
  70. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +9 -9
  71. data/spec/examples.txt +1717 -0
  72. data/spec/functional/accessible_spec.rb +19 -13
  73. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +13 -13
  74. data/spec/functional/associations/belongs_to_proxy_spec.rb +36 -20
  75. data/spec/functional/associations/in_array_proxy_spec.rb +145 -10
  76. data/spec/functional/associations/in_foreign_array_proxy_spec.rb +321 -0
  77. data/spec/functional/associations/many_documents_as_proxy_spec.rb +6 -6
  78. data/spec/functional/associations/many_documents_proxy_spec.rb +85 -14
  79. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +13 -13
  80. data/spec/functional/associations/many_embedded_proxy_spec.rb +1 -1
  81. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +4 -4
  82. data/spec/functional/associations/one_as_proxy_spec.rb +10 -10
  83. data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +9 -9
  84. data/spec/functional/associations/one_embedded_proxy_spec.rb +3 -3
  85. data/spec/functional/associations/one_proxy_spec.rb +10 -10
  86. data/spec/functional/associations_spec.rb +3 -3
  87. data/spec/functional/binary_spec.rb +2 -2
  88. data/spec/functional/caching_spec.rb +8 -15
  89. data/spec/functional/callbacks_spec.rb +89 -2
  90. data/spec/functional/counter_cache_spec.rb +235 -0
  91. data/spec/functional/dirty_spec.rb +63 -46
  92. data/spec/functional/document_spec.rb +30 -5
  93. data/spec/functional/dumpable_spec.rb +1 -1
  94. data/spec/functional/embedded_document_spec.rb +17 -17
  95. data/spec/functional/identity_map_spec.rb +29 -16
  96. data/spec/functional/indexes_spec.rb +19 -18
  97. data/spec/functional/keys_spec.rb +86 -28
  98. data/spec/functional/logger_spec.rb +3 -3
  99. data/spec/functional/modifiers_spec.rb +81 -19
  100. data/spec/functional/partial_updates_spec.rb +577 -0
  101. data/spec/functional/protected_spec.rb +14 -14
  102. data/spec/functional/querying_spec.rb +77 -28
  103. data/spec/functional/safe_spec.rb +23 -27
  104. data/spec/functional/sci_spec.rb +9 -9
  105. data/spec/functional/scopes_spec.rb +235 -2
  106. data/spec/functional/static_keys_spec.rb +153 -0
  107. data/spec/functional/stats_spec.rb +86 -0
  108. data/spec/functional/strong_parameters_spec.rb +49 -0
  109. data/spec/functional/touch_spec.rb +1 -1
  110. data/spec/functional/validations_spec.rb +51 -57
  111. data/spec/quality_spec.rb +51 -0
  112. data/spec/spec_helper.rb +37 -9
  113. data/spec/support/matchers.rb +5 -14
  114. data/spec/unit/associations/base_spec.rb +12 -12
  115. data/spec/unit/associations/belongs_to_association_spec.rb +2 -2
  116. data/spec/unit/associations/many_association_spec.rb +2 -2
  117. data/spec/unit/associations/one_association_spec.rb +2 -2
  118. data/spec/unit/associations/proxy_spec.rb +19 -20
  119. data/spec/unit/clone_spec.rb +1 -1
  120. data/spec/unit/document_spec.rb +8 -8
  121. data/spec/unit/dynamic_finder_spec.rb +8 -8
  122. data/spec/unit/embedded_document_spec.rb +18 -19
  123. data/spec/unit/extensions_spec.rb +41 -17
  124. data/spec/unit/identity_map_middleware_spec.rb +65 -96
  125. data/spec/unit/key_spec.rb +28 -26
  126. data/spec/unit/keys_spec.rb +20 -11
  127. data/spec/unit/model_generator_spec.rb +0 -0
  128. data/spec/unit/mongo_mapper_spec.rb +38 -85
  129. data/spec/unit/rails_spec.rb +5 -0
  130. data/spec/unit/serialization_spec.rb +1 -1
  131. data/spec/unit/time_zones_spec.rb +2 -2
  132. data/spec/unit/validations_spec.rb +46 -33
  133. metadata +66 -37
  134. data/README.rdoc +0 -59
  135. data/lib/mongo_mapper/connections/10gen.rb +0 -0
  136. data/lib/mongo_mapper/connections/moped.rb +0 -0
  137. data/lib/mongo_mapper/extensions/ordered_hash.rb +0 -23
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Stats" do
4
+ before(:each) do
5
+ class ::Docs
6
+ include MongoMapper::Document
7
+ key :title, String
8
+ key :published_at, Time
9
+ end
10
+
11
+ Docs.collection.drop
12
+ end
13
+
14
+ context "with no documents present" do
15
+ it "should return nil" do
16
+ if Docs.stats == nil
17
+ Docs.stats.should == nil
18
+ else
19
+ Docs.stats['count'].should == 0
20
+ end
21
+ end
22
+ end
23
+
24
+ context "with documents present" do
25
+ before do
26
+ # Make sure that there is at least one document stored
27
+ Docs.create!
28
+ end
29
+
30
+ def get_stats
31
+ MongoMapper.database.command(:collstats => 'docs').documents[0]
32
+ end
33
+
34
+ it "should have the correct count" do
35
+ Docs.stats.count.should == get_stats['count']
36
+ end
37
+
38
+ it "should have the correct namespace" do
39
+ Docs.stats.ns.should == get_stats['ns']
40
+ end
41
+
42
+ it "should have the correct size" do
43
+ Docs.stats.size.should == get_stats['size']
44
+ end
45
+
46
+ it "should have the correct storage size" do
47
+ Docs.stats.storage_size.should == get_stats['storageSize']
48
+ end
49
+
50
+ it "should have the correct average object size" do
51
+ Docs.stats.avg_obj_size.should == get_stats['avgObjSize']
52
+ end
53
+
54
+ it "should have the correct number of extents" do
55
+ if get_stats['numExtents']
56
+ Docs.stats.num_extents.should == get_stats['numExtents']
57
+ end
58
+ end
59
+
60
+ it "should have the correct number of indexes" do
61
+ Docs.stats.nindexes.should == get_stats['nindexes']
62
+ end
63
+
64
+ it "should have the correct last extent size" do
65
+ if get_stats['lastExtentSize']
66
+ Docs.stats.last_extent_size.should == get_stats['lastExtentSize']
67
+ end
68
+ end
69
+
70
+ it "should have the correct padding factor" do
71
+ if get_stats['paddingFactor']
72
+ Docs.stats.padding_factor.should == get_stats['paddingFactor']
73
+ end
74
+ end
75
+
76
+ it "should have the correct user flags" do
77
+ if get_stats['userFlags']
78
+ Docs.stats.user_flags.should == get_stats['userFlags']
79
+ end
80
+ end
81
+
82
+ it "should have the correct total index size" do
83
+ Docs.stats.total_index_size.should == get_stats['totalIndexSize']
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Strong parameters" do
4
+ context 'A document with strong parameters protection' do
5
+ if ::ActiveModel.const_defined?(:ForbiddenAttributesProtection)
6
+ require "action_controller/metal/strong_parameters"
7
+
8
+ before do
9
+ @doc_class = Doc do
10
+ plugin MongoMapper::Plugins::StrongParameters
11
+
12
+ key :name, String
13
+ key :admin, Boolean, :default => false
14
+ end
15
+
16
+ @doc = @doc_class.create(:name => 'Steve Sloan')
17
+ end
18
+
19
+ let(:params) {
20
+ {name: "Permitted", admin: true}
21
+ }
22
+
23
+ let(:strong_params) {
24
+ ActionController::Parameters.new params
25
+ }
26
+
27
+ it "allows assignment of attribute hashes" do
28
+ @doc.attributes = params
29
+ @doc.name.should =="Permitted"
30
+ end
31
+
32
+ it "doesn't allow mass assignment of ActionController::Parameters" do
33
+ lambda {
34
+ @doc.attributes = strong_params
35
+ }.should raise_error(ActiveModel::ForbiddenAttributesError)
36
+ end
37
+
38
+ it "does not allow mass assignment of non-permitted attributes" do
39
+ @doc.attributes = strong_params.permit(:name)
40
+ @doc.admin.should == false
41
+ end
42
+
43
+ it "allows mass assignment of permitted attributes" do
44
+ @doc.attributes = strong_params.permit(:name)
45
+ @doc.name.should == "Permitted"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -61,7 +61,7 @@ describe "Touch" do
61
61
 
62
62
  it 'should not be true by default' do
63
63
  @comment_class.belongs_to :post, :class => @post_class
64
- @comment_class.associations[:post].touch?.should_not be_true
64
+ @comment_class.associations[:post].touch?.should_not be_truthy
65
65
  end
66
66
 
67
67
  context 'touch the parent when true' do
@@ -57,7 +57,7 @@ describe "Validations" do
57
57
 
58
58
  it "should create a new document" do
59
59
  instance = @document.create!(:name => "James")
60
- instance.new_record?.should be_false
60
+ instance.new_record?.should be_falsey
61
61
  end
62
62
  end
63
63
 
@@ -140,7 +140,7 @@ describe "Validations" do
140
140
  validates_uniqueness_of :name, :scope => :adult
141
141
  end
142
142
  doc = document.new("name" => "joe", :adult => true)
143
- doc.save.should be_true
143
+ doc.save.should be_truthy
144
144
 
145
145
  doc2 = document.new("name" => "joe", :adult => false)
146
146
  doc2.should be_valid
@@ -149,31 +149,30 @@ describe "Validations" do
149
149
  it "should work with i18n taken message" do
150
150
  @document.create(:name => 'joe')
151
151
  doc = @document.create(:name => 'joe')
152
- doc.should have_error_on(:name, 'has already been taken')
152
+ doc.should have_error_on(:name)
153
+ doc.errors[:name].should == ['has already been taken']
153
154
  end
154
155
 
155
156
  it "should allow to update an object" do
156
157
  doc = @document.new("name" => "joe")
157
- doc.save.should be_true
158
+ doc.save.should be_truthy
158
159
 
159
- @document \
160
- .stub(:first) \
161
- .with(:name => 'joe') \
162
- .and_return(doc)
160
+ @document.stub(:first).
161
+ with(:name => 'joe').
162
+ and_return(doc)
163
163
 
164
164
  doc.name = "joe"
165
- doc.valid?.should be_true
165
+ doc.valid?.should be_truthy
166
166
  doc.should_not have_error_on(:name)
167
167
  end
168
168
 
169
169
  it "should fail if object name is not unique" do
170
170
  doc = @document.new("name" => "joe")
171
- doc.save.should be_true
171
+ doc.save.should be_truthy
172
172
 
173
- @document \
174
- .stub(:first) \
175
- .with(:name => 'joe') \
176
- .and_return(doc)
173
+ @document.stub(:first).
174
+ with(:name => 'joe').
175
+ and_return(doc)
177
176
 
178
177
  doc2 = @document.new("name" => "joe")
179
178
  doc2.should have_error_on(:name)
@@ -186,12 +185,11 @@ describe "Validations" do
186
185
  end
187
186
 
188
187
  doc = document.new("name" => "")
189
- doc.save.should be_true
188
+ doc.save.should be_truthy
190
189
 
191
- document \
192
- .stub(:first) \
193
- .with(:name => '') \
194
- .and_return(doc)
190
+ @document.stub(:first).
191
+ with(:name => '').
192
+ and_return(doc)
195
193
 
196
194
  doc2 = document.new("name" => "")
197
195
  doc2.should_not have_error_on(:name)
@@ -204,7 +202,7 @@ describe "Validations" do
204
202
  end
205
203
 
206
204
  doc = document.new('name' => nil)
207
- doc.save.should be_true
205
+ doc.save.should be_truthy
208
206
 
209
207
  doc2 = document.new('name' => nil)
210
208
  doc2.should_not have_error_on(:name)
@@ -217,7 +215,7 @@ describe "Validations" do
217
215
  end
218
216
 
219
217
  doc = document.new("name" => "BLAMMO")
220
- doc.save.should be_true
218
+ doc.save.should be_truthy
221
219
 
222
220
  doc2 = document.new("name" => "blammo")
223
221
  doc2.should_not have_error_on(:name)
@@ -233,7 +231,7 @@ describe "Validations" do
233
231
 
234
232
  it "should fail on entries that differ only in case" do
235
233
  doc = @document.new("name" => "BLAMMO")
236
- doc.save.should be_true
234
+ doc.save.should be_truthy
237
235
 
238
236
  doc2 = @document.new("name" => "blammo")
239
237
  doc2.should have_error_on(:name)
@@ -251,10 +249,10 @@ describe "Validations" do
251
249
 
252
250
  it "should check for uniqueness using entire string" do
253
251
  doc = @document.new("name" => "John Doe")
254
- doc.save.should be_true
252
+ doc.save.should be_truthy
255
253
 
256
254
  doc2 = @document.new("name" => "John")
257
- doc2.valid?.should be_true
255
+ doc2.valid?.should be_truthy
258
256
  end
259
257
  end
260
258
 
@@ -269,12 +267,11 @@ describe "Validations" do
269
267
 
270
268
  it "should fail if the same name exists in the scope" do
271
269
  doc = @document.new("name" => "joe", "scope" => "one")
272
- doc.save.should be_true
270
+ doc.save.should be_truthy
273
271
 
274
- @document \
275
- .stub(:first) \
276
- .with(:name => 'joe', :scope => "one") \
277
- .and_return(doc)
272
+ @document.stub(:first).
273
+ with(:name => 'joe', :scope => "one").
274
+ and_return(doc)
278
275
 
279
276
  doc2 = @document.new("name" => "joe", "scope" => "one")
280
277
  doc2.should have_error_on(:name)
@@ -282,12 +279,11 @@ describe "Validations" do
282
279
 
283
280
  it "should pass if the same name exists in a different scope" do
284
281
  doc = @document.new("name" => "joe", "scope" => "one")
285
- doc.save.should be_true
282
+ doc.save.should be_truthy
286
283
 
287
- @document \
288
- .stub(:first) \
289
- .with(:name => 'joe', :scope => 'two') \
290
- .and_return(nil)
284
+ @document.stub(:first).
285
+ with(:name => 'joe', :scope => 'two').
286
+ and_return(nil)
291
287
 
292
288
  doc2 = @document.new("name" => "joe", "scope" => "two")
293
289
  doc2.should_not have_error_on(:name)
@@ -306,12 +302,11 @@ describe "Validations" do
306
302
 
307
303
  it "should fail if the same name exists in the scope" do
308
304
  doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
309
- doc.save.should be_true
305
+ doc.save.should be_truthy
310
306
 
311
- @document \
312
- .stub(:first) \
313
- .with(:name => 'joe', :first_scope => 'one', :second_scope => 'two') \
314
- .and_return(doc)
307
+ @document.stub(:first).
308
+ with(:name => 'joe', :first_scope => 'one', :second_scope => 'two').
309
+ and_return(doc)
315
310
 
316
311
  doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
317
312
  doc2.should have_error_on(:name)
@@ -319,12 +314,11 @@ describe "Validations" do
319
314
 
320
315
  it "should pass if the same name exists in a different scope" do
321
316
  doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
322
- doc.save.should be_true
317
+ doc.save.should be_truthy
323
318
 
324
- @document \
325
- .stub(:first) \
326
- .with(:name => 'joe', :first_scope => 'one', :second_scope => 'one') \
327
- .and_return(nil)
319
+ @document.stub(:first).
320
+ with(:name => 'joe', :first_scope => 'one', :second_scope => 'one').
321
+ and_return(nil)
328
322
 
329
323
  doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "one")
330
324
  doc2.should_not have_error_on(:name)
@@ -345,21 +339,21 @@ describe "Validations" do
345
339
 
346
340
  it "should pass if there are no associated docs" do
347
341
  doc = @root_class.new
348
- doc.save.should be_true
342
+ doc.save.should be_truthy
349
343
  end
350
344
 
351
345
  it "should pass if the associated doc is valid" do
352
346
  doc = @root_class.new
353
347
  doc.children.build(:name => 'Joe')
354
- doc.save.should be_true
348
+ doc.save.should be_truthy
355
349
  end
356
350
 
357
351
  it "should fail if the associated doc is invalid" do
358
352
  doc = @root_class.new
359
353
  doc.children.build
360
- doc.should have_error_on(:children, 'are invalid')
354
+ doc.should have_error_on(:children)
355
+ doc.errors[:children].should == ['are invalid']
361
356
  end
362
-
363
357
  end
364
358
 
365
359
  context "validating associated docs with custom context" do
@@ -377,22 +371,22 @@ describe "Validations" do
377
371
 
378
372
  it "should pass if there are no associated docs" do
379
373
  doc = @root_class.new
380
- doc.valid?(:custom_context).should be_true
374
+ doc.valid?(:custom_context).should be_truthy
381
375
  end
382
376
 
383
377
  it "should pass if the associated doc is valid" do
384
378
  doc = @root_class.new
385
379
  doc.children.build(:name => 'George')
386
- doc.valid?(:custom_context).should be_true
380
+ doc.valid?(:custom_context).should be_truthy
387
381
  end
388
382
 
389
383
  it "should fail if the associated doc is invalid" do
390
384
  doc = @root_class.new
391
385
  doc.children.build(:name => 'Bob')
392
- doc.valid?(:custom_context).should_not be_true
386
+ doc.valid?(:custom_context).should_not be_truthy
393
387
  end
394
-
395
388
  end
389
+
396
390
  # context "validates uniqueness of with :unique shortcut" do
397
391
  # it "should work" do
398
392
  # @document = Doc do
@@ -402,13 +396,13 @@ describe "Validations" do
402
396
  # doc = @document.create(:name => 'John')
403
397
  # doc.should_not have_error_on(:name)
404
398
  #
405
- # @document \
406
- # .stub(:first) \
407
- # .with(:name => 'John') \
408
- # .and_return(doc)
399
+ # @document.stub(:first).
400
+ # with(:name => 'John').
401
+ # and_return(doc)
409
402
  #
410
403
  # second_john = @document.create(:name => 'John')
411
- # second_john.should have_error_on(:name, 'has already been taken')
404
+ # second_john.should have_error_on(:name)
405
+ # second_john.errors[:name].should == ['has already been taken']
412
406
  # end
413
407
  # end
414
408
  end
@@ -0,0 +1,51 @@
1
+ if defined?(Encoding) && Encoding.default_external != "UTF-8"
2
+ Encoding.default_external = "UTF-8"
3
+ end
4
+
5
+ describe "The library itself" do
6
+ def check_for_tab_characters(filename)
7
+ failing_lines = []
8
+ File.readlines(filename).each_with_index do |line,number|
9
+ failing_lines << number + 1 if line =~ /\t/
10
+ end
11
+
12
+ unless failing_lines.empty?
13
+ "#{filename} has tab characters on lines #{failing_lines.join(', ')}"
14
+ end
15
+ end
16
+
17
+ def check_for_extra_spaces(filename)
18
+ failing_lines = []
19
+ File.readlines(filename).each_with_index do |line,number|
20
+ next if line =~ /^\s+#.*\s+\n$/
21
+ failing_lines << number + 1 if line =~ /\s+\n$/
22
+ end
23
+
24
+ unless failing_lines.empty?
25
+ "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
26
+ end
27
+ end
28
+
29
+ RSpec::Matchers.define :be_well_formed do
30
+ failure_message do |actual|
31
+ actual.join("\n")
32
+ end
33
+
34
+ match do |actual|
35
+ actual.empty?
36
+ end
37
+ end
38
+
39
+ it "has no malformed whitespace" do
40
+ exempt = /\.gitmodules|\.marshal|fixtures|vendor|ssl_certs|kill|LICENSE/
41
+ error_messages = []
42
+ Dir.chdir(File.expand_path("../..", __FILE__)) do
43
+ `git ls-files`.split("\n").each do |filename|
44
+ next if filename =~ exempt
45
+ error_messages << check_for_tab_characters(filename)
46
+ error_messages << check_for_extra_spaces(filename)
47
+ end
48
+ end
49
+ error_messages.compact.should be_well_formed
50
+ end
51
+ end