mongoid_ext 0.6.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 (53) hide show
  1. data/.document +5 -0
  2. data/Gemfile +20 -0
  3. data/Gemfile.lock +50 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +17 -0
  6. data/Rakefile +44 -0
  7. data/VERSION +1 -0
  8. data/bin/mongoid_console +85 -0
  9. data/lib/mongoid_ext.rb +71 -0
  10. data/lib/mongoid_ext/criteria_ext.rb +15 -0
  11. data/lib/mongoid_ext/document_ext.rb +29 -0
  12. data/lib/mongoid_ext/file.rb +86 -0
  13. data/lib/mongoid_ext/file_list.rb +74 -0
  14. data/lib/mongoid_ext/file_server.rb +69 -0
  15. data/lib/mongoid_ext/filter.rb +266 -0
  16. data/lib/mongoid_ext/filter/parser.rb +71 -0
  17. data/lib/mongoid_ext/filter/result_set.rb +75 -0
  18. data/lib/mongoid_ext/js/filter.js +41 -0
  19. data/lib/mongoid_ext/js/find_tags.js +26 -0
  20. data/lib/mongoid_ext/js/tag_cloud.js +28 -0
  21. data/lib/mongoid_ext/modifiers.rb +93 -0
  22. data/lib/mongoid_ext/mongo_mapper.rb +63 -0
  23. data/lib/mongoid_ext/paranoia.rb +100 -0
  24. data/lib/mongoid_ext/patches.rb +17 -0
  25. data/lib/mongoid_ext/random.rb +23 -0
  26. data/lib/mongoid_ext/slugizer.rb +84 -0
  27. data/lib/mongoid_ext/storage.rb +110 -0
  28. data/lib/mongoid_ext/tags.rb +26 -0
  29. data/lib/mongoid_ext/types/embedded_hash.rb +25 -0
  30. data/lib/mongoid_ext/types/open_struct.rb +15 -0
  31. data/lib/mongoid_ext/types/timestamp.rb +15 -0
  32. data/lib/mongoid_ext/types/translation.rb +51 -0
  33. data/lib/mongoid_ext/update.rb +11 -0
  34. data/lib/mongoid_ext/versioning.rb +189 -0
  35. data/lib/mongoid_ext/voteable.rb +104 -0
  36. data/mongoid_ext.gemspec +129 -0
  37. data/test/helper.rb +30 -0
  38. data/test/models.rb +80 -0
  39. data/test/support/custom_matchers.rb +55 -0
  40. data/test/test_filter.rb +51 -0
  41. data/test/test_modifiers.rb +65 -0
  42. data/test/test_paranoia.rb +40 -0
  43. data/test/test_random.rb +57 -0
  44. data/test/test_slugizer.rb +66 -0
  45. data/test/test_storage.rb +110 -0
  46. data/test/test_tags.rb +47 -0
  47. data/test/test_update.rb +16 -0
  48. data/test/test_versioning.rb +55 -0
  49. data/test/test_voteable.rb +77 -0
  50. data/test/types/test_open_struct.rb +22 -0
  51. data/test/types/test_set.rb +26 -0
  52. data/test/types/test_timestamp.rb +40 -0
  53. metadata +301 -0
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+
3
+ class ModifiersTest < Test::Unit::TestCase
4
+ context "Modifying documents" do
5
+ setup do
6
+ @entry = Entry.create(:v => 345)
7
+ end
8
+
9
+ should "increment the value" do
10
+ Entry.increment({:_id => @entry.id}, {:v => 1})
11
+ @entry.reload
12
+ @entry.v.should == 346
13
+ end
14
+
15
+ should "decrement the value" do
16
+ @entry.decrement(:v => 1)
17
+ @entry.reload
18
+ @entry.v.should == 344
19
+ end
20
+
21
+ should "override the value" do
22
+ @entry.override(:v => 543)
23
+ @entry.reload
24
+ @entry.v.should == 543
25
+ end
26
+
27
+ should "unset the value" do
28
+ @entry.unset(:v => true)
29
+ @entry.reload
30
+ @entry.v.should == nil
31
+ end
32
+
33
+ should "push a value" do
34
+ @entry.push(:a => 1)
35
+ @entry.reload
36
+ @entry.a.should == [1]
37
+ end
38
+
39
+ should "not duplicate the value" do
40
+ @entry.push_uniq(:a => 1)
41
+ @entry.push_uniq(:a => 1)
42
+ @entry.push_uniq(:a => 1)
43
+ @entry.reload
44
+ @entry.a.should == [1]
45
+ end
46
+
47
+ should "pull a value" do
48
+ @entry.push_uniq(:a => 1)
49
+ @entry.push_uniq(:a => 2)
50
+ @entry.push_uniq(:a => 3)
51
+ @entry.pull(:a => 2)
52
+ @entry.reload
53
+ @entry.a.should == [1, 3]
54
+ end
55
+
56
+ should "pop the last value" do
57
+ @entry.push_uniq(:a => 1)
58
+ @entry.push_uniq(:a => 2)
59
+ @entry.push_uniq(:a => 3)
60
+ @entry.pop(:a => 1)
61
+ @entry.reload
62
+ @entry.a.should == [1, 2]
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,40 @@
1
+ require 'helper'
2
+
3
+ class TestParanoia < Test::Unit::TestCase
4
+ context "working with versions" do
5
+ setup do
6
+ User.delete_all
7
+ User.deleted.delete_all
8
+
9
+ @user = User.create(:login => "foo",
10
+ :email => "foo@bar.baz")
11
+ end
12
+
13
+ should "not delete permanently the record" do
14
+ @user.destroy
15
+ User.deleted.count.should == 1
16
+ User.count.should == 0
17
+ end
18
+
19
+ should "restore the deleted record" do
20
+ @user.destroy
21
+ User.deleted.first.restore.email.should == "foo@bar.baz"
22
+ end
23
+
24
+ should "delete the old records" do
25
+ @user.destroy
26
+ deleted = User.deleted.first
27
+ deleted.created_at = 2.months.ago
28
+ deleted.save
29
+
30
+ User.deleted.compact!
31
+ User.deleted.count.should == 0
32
+ end
33
+
34
+ should "find the record using the original id" do
35
+ id = @user.id
36
+ @user.destroy
37
+ User.deleted.find(id).should_not be_nil
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,57 @@
1
+ require 'helper'
2
+
3
+ class TestRandom < Test::Unit::TestCase
4
+ context "working with tags" do
5
+ setup do
6
+ end
7
+
8
+ should "find a random entry" do
9
+ Entry.random.should_not be_nil
10
+ Entry.random.should_not be_nil
11
+ Entry.random.should_not be_nil
12
+ end
13
+
14
+ should "increment the counter" do
15
+ entry = Entry.random
16
+ entry._random_times.should > 0
17
+ end
18
+
19
+ should "allow to pass conditions" do
20
+ entry = Entry.random(:v => 10)
21
+ entry.v.should == 10
22
+ end
23
+
24
+ #
25
+ # should "generate the tagcloud" do
26
+ # cloud = BlogPost.tag_cloud
27
+ #
28
+ # [{"name"=>"list", "count"=>2.0},
29
+ # {"name"=>"windows", "count"=>1.0},
30
+ # {"name"=>"freebsd", "count"=>1.0},
31
+ # {"name"=>"osx", "count"=>1.0},
32
+ # {"name"=>"linux", "count"=>1.0},
33
+ # {"name"=>"mongodb", "count"=>1.0},
34
+ # {"name"=>"redis", "count"=>1.0},
35
+ # {"name"=>"couchdb", "count"=>1.0}].each do |entry|
36
+ # cloud.should include(entry)
37
+ # end
38
+ # end
39
+ #
40
+ # should "find blogpost that include the given tags" do
41
+ # BlogPost.find_with_tags("mongodb").to_a.should == [@blogpost2]
42
+ # posts = BlogPost.find_with_tags("mongodb", "linux").to_a
43
+ # posts.should include(@blogpost)
44
+ # posts.should include(@blogpost2)
45
+ # posts.size.should == 2
46
+ # end
47
+ #
48
+ # should "find tags that start with li" do
49
+ # tags = BlogPost.find_tags(/^li/)
50
+ # [{"name"=>"list", "count"=>2.0}, {"name"=>"linux", "count"=>1.0}].each do |entry|
51
+ # tags.should include(entry)
52
+ # end
53
+ # tags.size.should == 2
54
+ # end
55
+
56
+ end
57
+ end
@@ -0,0 +1,66 @@
1
+ require 'helper'
2
+
3
+ class TestSlugizer < Test::Unit::TestCase
4
+ context "working with slugs" do
5
+ setup do
6
+ BlogPost.delete_all
7
+ @blogpost = BlogPost.create(:title => "%bLog pOSt tiTLe!",
8
+ :body => "HeRe is tHe Body of the bLog pOsT")
9
+ end
10
+
11
+ should "generate the slug" do
12
+ @blogpost.slug.should =~ /\w+-blog-post-title/
13
+ end
14
+
15
+ should "not generate the slug if the slug key is blank" do
16
+ @empty_blogpost = BlogPost.new
17
+ @empty_blogpost.slug.should be_nil
18
+ end
19
+
20
+ should "return the slug as param" do
21
+ @blogpost.to_param =~ /\w+-blog-post-title/
22
+ end
23
+
24
+ should "return the id if slug was not generated" do
25
+ @blogpost.slug = nil
26
+ @blogpost.to_param.should == @blogpost.id.to_s
27
+ end
28
+
29
+ should "respect the max length option" do
30
+ @blogpost = BlogPost.create(:title => "ultimo video/cancion en youtube?",
31
+ :body => "HeRe is tHe Body of the bLog pOsT")
32
+ @blogpost.slug.should =~ /\w+-ultimo-video-canci/
33
+ end
34
+
35
+ should "not accept slugs with length < :min_length" do
36
+ @blogpost = BlogPost.create(:title => "a",
37
+ :body => "HeRe is tHe Body of the bLog pOsT")
38
+ @blogpost.slug.should be_nil
39
+ end
40
+
41
+ should "update the slug after updating the object" do
42
+ @blogpost = BlogPost.create(:title => "ultimo video/cancion en youtube?",
43
+ :body => "HeRe is tHe Body of the bLog pOsT")
44
+ @blogpost.slug.should =~ /\w+-ultimo-video-canci/
45
+ @blogpost.title = "primer video/cancion en youtube?"
46
+ @blogpost.valid?
47
+ @blogpost.slug.should =~ /\w+-primer-video-canci/
48
+ end
49
+ end
50
+
51
+ context "finding objects" do
52
+ setup do
53
+ BlogPost.delete_all
54
+ @blogpost = BlogPost.create(:title => "%bLog pOSt tiTLe!",
55
+ :body => "HeRe is tHe Body of the bLog pOsT")
56
+ end
57
+
58
+ should "be able to find by slug" do
59
+ BlogPost.by_slug(@blogpost.slug).should == @blogpost
60
+ end
61
+
62
+ should "be able to find by id" do
63
+ BlogPost.by_slug(@blogpost.id).should == @blogpost
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,110 @@
1
+ require 'helper'
2
+
3
+ class StorageTest < Test::Unit::TestCase
4
+ context "Storing files" do
5
+ setup do
6
+ @avatar = Avatar.create
7
+ @data = StringIO.new("my avatar image")
8
+ end
9
+
10
+ should "store the file" do
11
+ @avatar.put_file("an_avatar.png", @data)
12
+ @avatar.save
13
+ avatar = Avatar.find(@avatar.id)
14
+ data = avatar.fetch_file("an_avatar.png").read
15
+ data.should == "my avatar image"
16
+ end
17
+
18
+ should "not close the file after storing" do
19
+ @avatar.put_file("an_avatar.png", @data)
20
+ @data.should_not be_closed
21
+ end
22
+
23
+ context "in attributes" do
24
+ should "store the given file" do
25
+ @avatar.data = @data
26
+ @avatar.save!
27
+ @avatar.data.should_not be_nil
28
+ @avatar.data.read.should == "my avatar image"
29
+ end
30
+ end
31
+
32
+ context "with new objects" do
33
+ setup do
34
+ @avatar = Avatar.new
35
+ end
36
+
37
+ should "store the data correctly" do
38
+ @avatar.data = @data
39
+ @avatar.save
40
+ @avatar = Avatar.find(@avatar.id)
41
+ @avatar.data.read.should == "my avatar image"
42
+ end
43
+
44
+ should "store the file after saving" do
45
+ @avatar.put_file("an_avatar.png", @data)
46
+ @avatar.save
47
+ @avatar.fetch_file("an_avatar.png").read.should == "my avatar image"
48
+ end
49
+
50
+ should "not store the file if object is new" do
51
+ @avatar.put_file("an_avatar.png", @data)
52
+ lambda {@avatar.fetch_file("an_avatar.png").read}.should raise_error
53
+ end
54
+ end
55
+
56
+ context "with lists" do
57
+ setup do
58
+ @avatar = Avatar.new
59
+ @alternative = File.new(__FILE__)
60
+ @data = File.read(__FILE__)
61
+ end
62
+ teardown do
63
+ @alternative.close
64
+ end
65
+
66
+ should "store the file" do
67
+ @avatar.first_alternative = @alternative
68
+ @avatar.save
69
+ fromdb = @avatar.reload
70
+ fromdb.first_alternative.read.should == @data
71
+ end
72
+
73
+ should "store the file in the alternative list" do
74
+ @avatar.alternatives.put("an_alternative", @alternative)
75
+ @avatar.save
76
+ @avatar.reload
77
+ @avatar.alternatives.get("an_alternative").read.should == @data
78
+ end
79
+ end
80
+ end
81
+
82
+ context "Fetching files" do
83
+ setup do
84
+ @avatar = Avatar.create
85
+ @data = StringIO.new("my avatar image")
86
+ end
87
+
88
+ should "fetch the list of files" do
89
+ @avatar.put_file("file1", StringIO.new("data1"))
90
+ @avatar.put_file("file2", StringIO.new("data2"))
91
+ @avatar.put_file("file3", StringIO.new("data3"))
92
+ file_names = @avatar.files.map { |f| f.filename }
93
+ file_names.size.should == 3
94
+ file_names.should include("file1")
95
+ file_names.should include("file2")
96
+ file_names.should include("file3")
97
+ end
98
+
99
+ should "iterate the list of files" do
100
+ @avatar.put_file("file1", StringIO.new("data1"))
101
+ @avatar.put_file("file2", StringIO.new("data2"))
102
+ @avatar.put_file("file3", StringIO.new("data3"))
103
+ file_names = %w[file1 file2 file3]
104
+ @avatar.file_list.each_file do |key, file|
105
+ file_names.should include key
106
+ file_names.should include file.filename
107
+ end
108
+ end
109
+ end
110
+ end
data/test/test_tags.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+
3
+ class TestTags < Test::Unit::TestCase
4
+ context "working with tags" do
5
+ setup do
6
+ BlogPost.delete_all
7
+ @blogpost = BlogPost.create(:title => "operation systems",
8
+ :body => "list of some operating systems",
9
+ :tags => %w[list windows freebsd osx linux])
10
+ @blogpost2 = BlogPost.create(:title => "nosql database",
11
+ :body => "list of some nosql databases",
12
+ :tags => %w[list mongodb redis couchdb])
13
+ end
14
+
15
+ should "generate the tagcloud" do
16
+ cloud = BlogPost.tag_cloud
17
+
18
+ [{"name"=>"list", "count"=>2.0},
19
+ {"name"=>"windows", "count"=>1.0},
20
+ {"name"=>"freebsd", "count"=>1.0},
21
+ {"name"=>"osx", "count"=>1.0},
22
+ {"name"=>"linux", "count"=>1.0},
23
+ {"name"=>"mongodb", "count"=>1.0},
24
+ {"name"=>"redis", "count"=>1.0},
25
+ {"name"=>"couchdb", "count"=>1.0}].each do |entry|
26
+ cloud.should include(entry)
27
+ end
28
+ end
29
+
30
+ should "find blogpost that include the given tags" do
31
+ BlogPost.find_with_tags("mongodb").to_a.should == [@blogpost2]
32
+ posts = BlogPost.find_with_tags("mongodb", "linux").to_a
33
+ posts.should include(@blogpost)
34
+ posts.should include(@blogpost2)
35
+ posts.size.should == 2
36
+ end
37
+
38
+ should "find tags that start with li" do
39
+ tags = BlogPost.find_tags(/^li/)
40
+ [{"name"=>"list", "count"=>2.0}, {"name"=>"linux", "count"=>1.0}].each do |entry|
41
+ tags.should include(entry)
42
+ end
43
+ tags.size.should == 2
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+
3
+ class UpdateTest < Test::Unit::TestCase
4
+ should "only update the given white listed attributes" do
5
+ event = Event.new(:password => "original")
6
+ start_date = Time.zone.now
7
+ end_date = start_date.tomorrow
8
+
9
+ event.safe_update(%w[start_date end_date], {"start_date" => start_date,
10
+ "end_date" => end_date,
11
+ "password" => "hacked"})
12
+ event.password.should == "original"
13
+ event.start_date.to_s.should == start_date.to_s
14
+ event.end_date.to_s.should == end_date.to_s
15
+ end
16
+ end
@@ -0,0 +1,55 @@
1
+ require 'helper'
2
+
3
+ class TestVersioning < Test::Unit::TestCase
4
+ context "working with versions" do
5
+ setup do
6
+ BlogPost.delete_all
7
+ User.delete_all
8
+
9
+ @blogpost = BlogPost.create(:title => "operating systems",
10
+ :body => "list of some operating systems",
11
+ :tags => %w[list windows freebsd osx linux],
12
+ :updated_by => User.create(:login => "foo"))
13
+ end
14
+
15
+ should "generate a new version" do
16
+ @blogpost.versions_count.should == 0
17
+ @blogpost.title = "sistemas operativos"
18
+ @blogpost.save!
19
+ @blogpost.reload
20
+ @blogpost.versions_count.should == 1
21
+ end
22
+
23
+ should "be able to generate a diff between versions" do
24
+ @blogpost.title = "sistemas operativos"
25
+ @blogpost.save!
26
+ @blogpost.reload
27
+
28
+ @blogpost.diff(:title, "current", 0, :ascii).should == '{+"sistemas operativos"}'
29
+ @blogpost.diff(:title, 0, "current", :ascii).should == '{-"sistemas operativos"}'
30
+ end
31
+
32
+ should "be able to restore a previous version" do
33
+ @blogpost.title = "sistemas operativos"
34
+ @blogpost.save!
35
+ @blogpost.reload
36
+
37
+ @blogpost.title.should == "sistemas operativos"
38
+ @blogpost.rollback!(0)
39
+ @blogpost.title.should == "operating systems"
40
+ end
41
+
42
+ should "respect the max versions limit" do
43
+ @blogpost.title = "sistemas operativos"
44
+ @blogpost.save!
45
+ @blogpost.reload
46
+ @blogpost.title = "sistemas operativos 2"
47
+ @blogpost.save!
48
+ @blogpost.reload
49
+ @blogpost.title = "sistemas operativos 3"
50
+ @blogpost.save!
51
+ @blogpost.reload
52
+ @blogpost.versions.count.should == 2
53
+ end
54
+ end
55
+ end