openlogic-couchrest_model 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/.gitignore +11 -0
  2. data/.rspec +4 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +176 -0
  5. data/README.md +137 -0
  6. data/Rakefile +38 -0
  7. data/THANKS.md +21 -0
  8. data/VERSION +1 -0
  9. data/benchmarks/dirty.rb +118 -0
  10. data/couchrest_model.gemspec +36 -0
  11. data/history.md +309 -0
  12. data/init.rb +1 -0
  13. data/lib/couchrest/model.rb +10 -0
  14. data/lib/couchrest/model/associations.rb +231 -0
  15. data/lib/couchrest/model/base.rb +129 -0
  16. data/lib/couchrest/model/callbacks.rb +28 -0
  17. data/lib/couchrest/model/casted_array.rb +83 -0
  18. data/lib/couchrest/model/casted_by.rb +33 -0
  19. data/lib/couchrest/model/casted_hash.rb +84 -0
  20. data/lib/couchrest/model/class_proxy.rb +135 -0
  21. data/lib/couchrest/model/collection.rb +273 -0
  22. data/lib/couchrest/model/configuration.rb +67 -0
  23. data/lib/couchrest/model/connection.rb +70 -0
  24. data/lib/couchrest/model/core_extensions/hash.rb +9 -0
  25. data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
  26. data/lib/couchrest/model/design_doc.rb +128 -0
  27. data/lib/couchrest/model/designs.rb +91 -0
  28. data/lib/couchrest/model/designs/view.rb +513 -0
  29. data/lib/couchrest/model/dirty.rb +39 -0
  30. data/lib/couchrest/model/document_queries.rb +99 -0
  31. data/lib/couchrest/model/embeddable.rb +78 -0
  32. data/lib/couchrest/model/errors.rb +25 -0
  33. data/lib/couchrest/model/extended_attachments.rb +83 -0
  34. data/lib/couchrest/model/persistence.rb +178 -0
  35. data/lib/couchrest/model/properties.rb +228 -0
  36. data/lib/couchrest/model/property.rb +114 -0
  37. data/lib/couchrest/model/property_protection.rb +71 -0
  38. data/lib/couchrest/model/proxyable.rb +183 -0
  39. data/lib/couchrest/model/support/couchrest_database.rb +13 -0
  40. data/lib/couchrest/model/support/couchrest_design.rb +33 -0
  41. data/lib/couchrest/model/typecast.rb +154 -0
  42. data/lib/couchrest/model/validations.rb +80 -0
  43. data/lib/couchrest/model/validations/casted_model.rb +16 -0
  44. data/lib/couchrest/model/validations/locale/en.yml +5 -0
  45. data/lib/couchrest/model/validations/uniqueness.rb +69 -0
  46. data/lib/couchrest/model/views.rb +151 -0
  47. data/lib/couchrest/railtie.rb +24 -0
  48. data/lib/couchrest_model.rb +66 -0
  49. data/lib/rails/generators/couchrest_model.rb +16 -0
  50. data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
  51. data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
  52. data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
  53. data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
  54. data/spec/.gitignore +1 -0
  55. data/spec/fixtures/attachments/README +3 -0
  56. data/spec/fixtures/attachments/couchdb.png +0 -0
  57. data/spec/fixtures/attachments/test.html +11 -0
  58. data/spec/fixtures/config/couchdb.yml +10 -0
  59. data/spec/fixtures/models/article.rb +36 -0
  60. data/spec/fixtures/models/base.rb +164 -0
  61. data/spec/fixtures/models/card.rb +19 -0
  62. data/spec/fixtures/models/cat.rb +23 -0
  63. data/spec/fixtures/models/client.rb +6 -0
  64. data/spec/fixtures/models/course.rb +27 -0
  65. data/spec/fixtures/models/event.rb +8 -0
  66. data/spec/fixtures/models/invoice.rb +14 -0
  67. data/spec/fixtures/models/key_chain.rb +5 -0
  68. data/spec/fixtures/models/membership.rb +4 -0
  69. data/spec/fixtures/models/person.rb +11 -0
  70. data/spec/fixtures/models/project.rb +6 -0
  71. data/spec/fixtures/models/question.rb +7 -0
  72. data/spec/fixtures/models/sale_entry.rb +9 -0
  73. data/spec/fixtures/models/sale_invoice.rb +14 -0
  74. data/spec/fixtures/models/service.rb +10 -0
  75. data/spec/fixtures/models/user.rb +22 -0
  76. data/spec/fixtures/views/lib.js +3 -0
  77. data/spec/fixtures/views/test_view/lib.js +3 -0
  78. data/spec/fixtures/views/test_view/only-map.js +4 -0
  79. data/spec/fixtures/views/test_view/test-map.js +3 -0
  80. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  81. data/spec/functional/validations_spec.rb +8 -0
  82. data/spec/spec_helper.rb +60 -0
  83. data/spec/unit/active_model_lint_spec.rb +30 -0
  84. data/spec/unit/assocations_spec.rb +242 -0
  85. data/spec/unit/attachment_spec.rb +176 -0
  86. data/spec/unit/base_spec.rb +537 -0
  87. data/spec/unit/casted_spec.rb +72 -0
  88. data/spec/unit/class_proxy_spec.rb +167 -0
  89. data/spec/unit/collection_spec.rb +86 -0
  90. data/spec/unit/configuration_spec.rb +77 -0
  91. data/spec/unit/connection_spec.rb +148 -0
  92. data/spec/unit/core_extensions/time_parsing.rb +77 -0
  93. data/spec/unit/design_doc_spec.rb +241 -0
  94. data/spec/unit/designs/view_spec.rb +831 -0
  95. data/spec/unit/designs_spec.rb +134 -0
  96. data/spec/unit/dirty_spec.rb +436 -0
  97. data/spec/unit/embeddable_spec.rb +498 -0
  98. data/spec/unit/inherited_spec.rb +33 -0
  99. data/spec/unit/persistence_spec.rb +481 -0
  100. data/spec/unit/property_protection_spec.rb +192 -0
  101. data/spec/unit/property_spec.rb +481 -0
  102. data/spec/unit/proxyable_spec.rb +376 -0
  103. data/spec/unit/subclass_spec.rb +85 -0
  104. data/spec/unit/typecast_spec.rb +521 -0
  105. data/spec/unit/validations_spec.rb +140 -0
  106. data/spec/unit/view_spec.rb +367 -0
  107. metadata +301 -0
@@ -0,0 +1,521 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "Type Casting" do
5
+
6
+ before(:each) do
7
+ @course = Course.new(:title => 'Relaxation')
8
+ end
9
+
10
+ describe "when value is nil" do
11
+ it "leaves the value unchanged" do
12
+ @course.title = nil
13
+ @course['title'].should == nil
14
+ end
15
+ end
16
+
17
+ describe "when type primitive is an Object" do
18
+ it "it should not cast given value" do
19
+ @course.participants = [{}, 'q', 1]
20
+ @course['participants'].should == [{}, 'q', 1]
21
+ end
22
+
23
+ it "should cast started_on to Date" do
24
+ @course.started_on = Date.today
25
+ @course['started_on'].should be_an_instance_of(Date)
26
+ end
27
+ end
28
+
29
+ describe "when type primitive is a String" do
30
+ it "keeps string value unchanged" do
31
+ value = "1.0"
32
+ @course.title = value
33
+ @course['title'].should equal(value)
34
+ end
35
+
36
+ it "it casts to string representation of the value" do
37
+ @course.title = 1.0
38
+ @course['title'].should eql("1.0")
39
+ end
40
+ end
41
+
42
+ describe 'when type primitive is a Float' do
43
+ it 'returns same value if a float' do
44
+ value = 24.0
45
+ @course.estimate = value
46
+ @course['estimate'].should equal(value)
47
+ end
48
+
49
+ it 'returns float representation of a zero string integer' do
50
+ @course.estimate = '0'
51
+ @course['estimate'].should eql(0.0)
52
+ end
53
+
54
+ it 'returns float representation of a positive string integer' do
55
+ @course.estimate = '24'
56
+ @course['estimate'].should eql(24.0)
57
+ end
58
+
59
+ it 'returns float representation of a negative string integer' do
60
+ @course.estimate = '-24'
61
+ @course['estimate'].should eql(-24.0)
62
+ end
63
+
64
+ it 'returns float representation of a zero string float' do
65
+ @course.estimate = '0.0'
66
+ @course['estimate'].should eql(0.0)
67
+ end
68
+
69
+ it 'returns float representation of a positive string float' do
70
+ @course.estimate = '24.35'
71
+ @course['estimate'].should eql(24.35)
72
+ end
73
+
74
+ it 'returns float representation of a negative string float' do
75
+ @course.estimate = '-24.35'
76
+ @course['estimate'].should eql(-24.35)
77
+ end
78
+
79
+ it 'returns float representation of a zero string float, with no leading digits' do
80
+ @course.estimate = '.0'
81
+ @course['estimate'].should eql(0.0)
82
+ end
83
+
84
+ it 'returns float representation of a positive string float, with no leading digits' do
85
+ @course.estimate = '.41'
86
+ @course['estimate'].should eql(0.41)
87
+ end
88
+
89
+ it 'returns float representation of a zero integer' do
90
+ @course.estimate = 0
91
+ @course['estimate'].should eql(0.0)
92
+ end
93
+
94
+ it 'returns float representation of a positive integer' do
95
+ @course.estimate = 24
96
+ @course['estimate'].should eql(24.0)
97
+ end
98
+
99
+ it 'returns float representation of a negative integer' do
100
+ @course.estimate = -24
101
+ @course['estimate'].should eql(-24.0)
102
+ end
103
+
104
+ it 'returns float representation of a zero decimal' do
105
+ @course.estimate = BigDecimal('0.0')
106
+ @course['estimate'].should eql(0.0)
107
+ end
108
+
109
+ it 'returns float representation of a positive decimal' do
110
+ @course.estimate = BigDecimal('24.35')
111
+ @course['estimate'].should eql(24.35)
112
+ end
113
+
114
+ it 'returns float representation of a negative decimal' do
115
+ @course.estimate = BigDecimal('-24.35')
116
+ @course['estimate'].should eql(-24.35)
117
+ end
118
+
119
+ it 'return float of a number with commas instead of points for decimals' do
120
+ @course.estimate = '23,35'
121
+ @course['estimate'].should eql(23.35)
122
+ end
123
+
124
+ it "should handle numbers with commas and points" do
125
+ @course.estimate = '1,234.00'
126
+ @course.estimate.should eql(1234.00)
127
+ end
128
+
129
+ it "should handle a mis-match of commas and points and maintain the last one" do
130
+ @course.estimate = "1,232.434.123,323"
131
+ @course.estimate.should eql(1232434123.323)
132
+ end
133
+
134
+ it "should handle numbers with whitespace" do
135
+ @course.estimate = " 24.35 "
136
+ @course.estimate.should eql(24.35)
137
+ end
138
+
139
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
140
+ it "does not typecast non-numeric value #{value.inspect}" do
141
+ @course.estimate = value
142
+ @course['estimate'].should equal(value)
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ describe 'when type primitive is a Integer' do
149
+ it 'returns same value if an integer' do
150
+ value = 24
151
+ @course.hours = value
152
+ @course['hours'].should equal(value)
153
+ end
154
+
155
+ it 'returns integer representation of a zero string integer' do
156
+ @course.hours = '0'
157
+ @course['hours'].should eql(0)
158
+ end
159
+
160
+ it 'returns integer representation of a positive string integer' do
161
+ @course.hours = '24'
162
+ @course['hours'].should eql(24)
163
+ end
164
+
165
+ it 'returns integer representation of a negative string integer' do
166
+ @course.hours = '-24'
167
+ @course['hours'].should eql(-24)
168
+ end
169
+
170
+ it 'returns integer representation of a zero string float' do
171
+ @course.hours = '0.0'
172
+ @course['hours'].should eql(0)
173
+ end
174
+
175
+ it 'returns integer representation of a positive string float' do
176
+ @course.hours = '24.35'
177
+ @course['hours'].should eql(24)
178
+ end
179
+
180
+ it 'returns integer representation of a negative string float' do
181
+ @course.hours = '-24.35'
182
+ @course['hours'].should eql(-24)
183
+ end
184
+
185
+ it 'returns integer representation of a zero string float, with no leading digits' do
186
+ @course.hours = '.0'
187
+ @course['hours'].should eql(0)
188
+ end
189
+
190
+ it 'returns integer representation of a positive string float, with no leading digits' do
191
+ @course.hours = '.41'
192
+ @course['hours'].should eql(0)
193
+ end
194
+
195
+ it 'returns integer representation of a zero float' do
196
+ @course.hours = 0.0
197
+ @course['hours'].should eql(0)
198
+ end
199
+
200
+ it 'returns integer representation of a positive float' do
201
+ @course.hours = 24.35
202
+ @course['hours'].should eql(24)
203
+ end
204
+
205
+ it 'returns integer representation of a negative float' do
206
+ @course.hours = -24.35
207
+ @course['hours'].should eql(-24)
208
+ end
209
+
210
+ it 'returns integer representation of a zero decimal' do
211
+ @course.hours = '0.0'
212
+ @course['hours'].should eql(0)
213
+ end
214
+
215
+ it 'returns integer representation of a positive decimal' do
216
+ @course.hours = '24.35'
217
+ @course['hours'].should eql(24)
218
+ end
219
+
220
+ it 'returns integer representation of a negative decimal' do
221
+ @course.hours = '-24.35'
222
+ @course['hours'].should eql(-24)
223
+ end
224
+
225
+ it "should handle numbers with whitespace" do
226
+ @course.hours = " 24 "
227
+ @course['hours'].should eql(24)
228
+ end
229
+
230
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
231
+ it "does not typecast non-numeric value #{value.inspect}" do
232
+ @course.hours = value
233
+ @course['hours'].should equal(value)
234
+ end
235
+ end
236
+ end
237
+
238
+ describe 'when type primitive is a BigDecimal' do
239
+ it 'returns same value if a decimal' do
240
+ value = BigDecimal('24.0')
241
+ @course.profit = value
242
+ @course['profit'].should equal(value)
243
+ end
244
+
245
+ it 'returns decimal representation of a zero string integer' do
246
+ @course.profit = '0'
247
+ @course['profit'].should eql(BigDecimal('0.0'))
248
+ end
249
+
250
+ it 'returns decimal representation of a positive string integer' do
251
+ @course.profit = '24'
252
+ @course['profit'].should eql(BigDecimal('24.0'))
253
+ end
254
+
255
+ it 'returns decimal representation of a negative string integer' do
256
+ @course.profit = '-24'
257
+ @course['profit'].should eql(BigDecimal('-24.0'))
258
+ end
259
+
260
+ it 'returns decimal representation of a zero string float' do
261
+ @course.profit = '0.0'
262
+ @course['profit'].should eql(BigDecimal('0.0'))
263
+ end
264
+
265
+ it 'returns decimal representation of a positive string float' do
266
+ @course.profit = '24.35'
267
+ @course['profit'].should eql(BigDecimal('24.35'))
268
+ end
269
+
270
+ it 'returns decimal representation of a negative string float' do
271
+ @course.profit = '-24.35'
272
+ @course['profit'].should eql(BigDecimal('-24.35'))
273
+ end
274
+
275
+ it 'returns decimal representation of a zero string float, with no leading digits' do
276
+ @course.profit = '.0'
277
+ @course['profit'].should eql(BigDecimal('0.0'))
278
+ end
279
+
280
+ it 'returns decimal representation of a positive string float, with no leading digits' do
281
+ @course.profit = '.41'
282
+ @course['profit'].should eql(BigDecimal('0.41'))
283
+ end
284
+
285
+ it 'returns decimal representation of a zero integer' do
286
+ @course.profit = 0
287
+ @course['profit'].should eql(BigDecimal('0.0'))
288
+ end
289
+
290
+ it 'returns decimal representation of a positive integer' do
291
+ @course.profit = 24
292
+ @course['profit'].should eql(BigDecimal('24.0'))
293
+ end
294
+
295
+ it 'returns decimal representation of a negative integer' do
296
+ @course.profit = -24
297
+ @course['profit'].should eql(BigDecimal('-24.0'))
298
+ end
299
+
300
+ it 'returns decimal representation of a zero float' do
301
+ @course.profit = 0.0
302
+ @course['profit'].should eql(BigDecimal('0.0'))
303
+ end
304
+
305
+ it 'returns decimal representation of a positive float' do
306
+ @course.profit = 24.35
307
+ @course['profit'].should eql(BigDecimal('24.35'))
308
+ end
309
+
310
+ it 'returns decimal representation of a negative float' do
311
+ @course.profit = -24.35
312
+ @course['profit'].should eql(BigDecimal('-24.35'))
313
+ end
314
+
315
+ it "should handle numbers with whitespace" do
316
+ @course.profit = " 24.35 "
317
+ @course['profit'].should eql(BigDecimal('24.35'))
318
+ end
319
+
320
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
321
+ it "does not typecast non-numeric value #{value.inspect}" do
322
+ @course.profit = value
323
+ @course['profit'].should equal(value)
324
+ end
325
+ end
326
+ end
327
+
328
+ describe 'when type primitive is a DateTime' do
329
+ describe 'and value given as a hash with keys like :year, :month, etc' do
330
+ it 'builds a DateTime instance from hash values' do
331
+ @course.updated_at = {
332
+ :year => '2006',
333
+ :month => '11',
334
+ :day => '23',
335
+ :hour => '12',
336
+ :min => '0',
337
+ :sec => '0'
338
+ }
339
+ result = @course['updated_at']
340
+
341
+ result.should be_kind_of(DateTime)
342
+ result.year.should eql(2006)
343
+ result.month.should eql(11)
344
+ result.day.should eql(23)
345
+ result.hour.should eql(12)
346
+ result.min.should eql(0)
347
+ result.sec.should eql(0)
348
+ end
349
+ end
350
+
351
+ describe 'and value is a string' do
352
+ it 'parses the string' do
353
+ @course.updated_at = 'Dec, 2006'
354
+ @course['updated_at'].month.should == 12
355
+ end
356
+ end
357
+
358
+ it 'does not typecast non-datetime values' do
359
+ @course.updated_at = 'not-datetime'
360
+ @course['updated_at'].should eql('not-datetime')
361
+ end
362
+ end
363
+
364
+ describe 'when type primitive is a Date' do
365
+ describe 'and value given as a hash with keys like :year, :month, etc' do
366
+ it 'builds a Date instance from hash values' do
367
+ @course.started_on = {
368
+ :year => '2007',
369
+ :month => '3',
370
+ :day => '25'
371
+ }
372
+ result = @course['started_on']
373
+
374
+ result.should be_kind_of(Date)
375
+ result.year.should eql(2007)
376
+ result.month.should eql(3)
377
+ result.day.should eql(25)
378
+ end
379
+ end
380
+
381
+ describe 'and value is a string' do
382
+ it 'parses the string' do
383
+ @course.started_on = 'Dec 20th, 2006'
384
+ @course.started_on.month.should == 12
385
+ @course.started_on.day.should == 20
386
+ @course.started_on.year.should == 2006
387
+ end
388
+ end
389
+
390
+ it 'does not typecast non-date values' do
391
+ @course.started_on = 'not-date'
392
+ @course['started_on'].should eql('not-date')
393
+ end
394
+ end
395
+
396
+ describe 'when type primitive is a Time' do
397
+ describe 'and value given as a hash with keys like :year, :month, etc' do
398
+ it 'builds a Time instance from hash values' do
399
+ @course.ends_at = {
400
+ :year => '2006',
401
+ :month => '11',
402
+ :day => '23',
403
+ :hour => '12',
404
+ :min => '0',
405
+ :sec => '0'
406
+ }
407
+ result = @course['ends_at']
408
+
409
+ result.should be_kind_of(Time)
410
+ result.year.should eql(2006)
411
+ result.month.should eql(11)
412
+ result.day.should eql(23)
413
+ result.hour.should eql(12)
414
+ result.min.should eql(0)
415
+ result.sec.should eql(0)
416
+ end
417
+ end
418
+
419
+ describe 'and value is a string' do
420
+ it 'parses the string' do
421
+ t = Time.new(2011, 4, 1, 18, 50, 32, "+02:00")
422
+ @course.ends_at = t.strftime('%Y/%m/%d %H:%M:%S %z')
423
+ @course['ends_at'].year.should eql(t.year)
424
+ @course['ends_at'].month.should eql(t.month)
425
+ @course['ends_at'].day.should eql(t.day)
426
+ @course['ends_at'].hour.should eql(t.hour)
427
+ @course['ends_at'].min.should eql(t.min)
428
+ @course['ends_at'].sec.should eql(t.sec)
429
+ end
430
+ it 'parses the string without offset as UTC' do
431
+ t = Time.now.utc
432
+ @course.ends_at = t.strftime("%Y-%m-%d %H:%M:%S")
433
+ @course.ends_at.utc?.should be_true
434
+ @course['ends_at'].year.should eql(t.year)
435
+ @course['ends_at'].month.should eql(t.month)
436
+ @course['ends_at'].day.should eql(t.day)
437
+ @course['ends_at'].hour.should eql(t.hour)
438
+ @course['ends_at'].min.should eql(t.min)
439
+ @course['ends_at'].sec.should eql(t.sec)
440
+ end
441
+ end
442
+
443
+ it "converts a time value into utc" do
444
+ t = Time.new(2011, 4, 1, 18, 50, 32, "+02:00")
445
+ @course.ends_at = t
446
+ @course.ends_at.utc?.should be_true
447
+ @course.ends_at.to_i.should eql(Time.utc(2011, 4, 1, 16, 50, 32).to_i)
448
+ end
449
+
450
+ if RUBY_VERSION >= "1.9.1"
451
+ # In ruby 1.8.7 Time.parse will always return a value. D'OH
452
+ it 'does not typecast non-time values' do
453
+ @course.ends_at = 'not-time'
454
+ @course['ends_at'].should eql('not-time')
455
+ end
456
+ end
457
+ end
458
+
459
+ describe 'when type primitive is a Class' do
460
+ it 'returns same value if a class' do
461
+ value = Course
462
+ @course.klass = value
463
+ @course['klass'].should equal(value)
464
+ end
465
+
466
+ it 'returns the class if found' do
467
+ @course.klass = 'Course'
468
+ @course['klass'].should eql(Course)
469
+ end
470
+
471
+ it 'does not typecast non-class values' do
472
+ @course.klass = 'NoClass'
473
+ @course['klass'].should eql('NoClass')
474
+ end
475
+ end
476
+
477
+ describe 'when type primitive is a Boolean' do
478
+
479
+ [ true, 'true', 'TRUE', '1', 1, 't', 'T' ].each do |value|
480
+ it "returns true when value is #{value.inspect}" do
481
+ @course.active = value
482
+ @course['active'].should be_true
483
+ end
484
+ end
485
+
486
+ [ false, 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
487
+ it "returns false when value is #{value.inspect}" do
488
+ @course.active = value
489
+ @course['active'].should be_false
490
+ end
491
+ end
492
+
493
+ [ 'string', 2, 1.0, BigDecimal('1.0'), DateTime.now, Time.now, Date.today, Class, Object.new, ].each do |value|
494
+ it "does not typecast value #{value.inspect}" do
495
+ @course.active = value
496
+ @course['active'].should equal(value)
497
+ end
498
+ end
499
+
500
+ it "should respond to requests with ? modifier" do
501
+ @course.active = nil
502
+ @course.active?.should be_false
503
+ @course.active = false
504
+ @course.active?.should be_false
505
+ @course.active = true
506
+ @course.active?.should be_true
507
+ end
508
+
509
+ it "should respond to requests with ? modifier on TrueClass" do
510
+ @course.very_active = nil
511
+ @course.very_active?.should be_false
512
+ @course.very_active = false
513
+ @course.very_active?.should be_false
514
+ @course.very_active = true
515
+ @course.very_active?.should be_true
516
+ end
517
+ end
518
+
519
+ end
520
+
521
+