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.
- 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
|