mongoid_ext 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
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