mongoid_ext 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +50 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +44 -0
- data/VERSION +1 -0
- data/bin/mongoid_console +85 -0
- data/lib/mongoid_ext.rb +71 -0
- data/lib/mongoid_ext/criteria_ext.rb +15 -0
- data/lib/mongoid_ext/document_ext.rb +29 -0
- data/lib/mongoid_ext/file.rb +86 -0
- data/lib/mongoid_ext/file_list.rb +74 -0
- data/lib/mongoid_ext/file_server.rb +69 -0
- data/lib/mongoid_ext/filter.rb +266 -0
- data/lib/mongoid_ext/filter/parser.rb +71 -0
- data/lib/mongoid_ext/filter/result_set.rb +75 -0
- data/lib/mongoid_ext/js/filter.js +41 -0
- data/lib/mongoid_ext/js/find_tags.js +26 -0
- data/lib/mongoid_ext/js/tag_cloud.js +28 -0
- data/lib/mongoid_ext/modifiers.rb +93 -0
- data/lib/mongoid_ext/mongo_mapper.rb +63 -0
- data/lib/mongoid_ext/paranoia.rb +100 -0
- data/lib/mongoid_ext/patches.rb +17 -0
- data/lib/mongoid_ext/random.rb +23 -0
- data/lib/mongoid_ext/slugizer.rb +84 -0
- data/lib/mongoid_ext/storage.rb +110 -0
- data/lib/mongoid_ext/tags.rb +26 -0
- data/lib/mongoid_ext/types/embedded_hash.rb +25 -0
- data/lib/mongoid_ext/types/open_struct.rb +15 -0
- data/lib/mongoid_ext/types/timestamp.rb +15 -0
- data/lib/mongoid_ext/types/translation.rb +51 -0
- data/lib/mongoid_ext/update.rb +11 -0
- data/lib/mongoid_ext/versioning.rb +189 -0
- data/lib/mongoid_ext/voteable.rb +104 -0
- data/mongoid_ext.gemspec +129 -0
- data/test/helper.rb +30 -0
- data/test/models.rb +80 -0
- data/test/support/custom_matchers.rb +55 -0
- data/test/test_filter.rb +51 -0
- data/test/test_modifiers.rb +65 -0
- data/test/test_paranoia.rb +40 -0
- data/test/test_random.rb +57 -0
- data/test/test_slugizer.rb +66 -0
- data/test/test_storage.rb +110 -0
- data/test/test_tags.rb +47 -0
- data/test/test_update.rb +16 -0
- data/test/test_versioning.rb +55 -0
- data/test/test_voteable.rb +77 -0
- data/test/types/test_open_struct.rb +22 -0
- data/test/types/test_set.rb +26 -0
- data/test/types/test_timestamp.rb +40 -0
- 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
|
data/test/test_random.rb
ADDED
@@ -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
|
data/test/test_update.rb
ADDED
@@ -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
|