wayne-friendly 0.5.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 +2 -0
- data/.gitignore +26 -0
- data/APACHE-LICENSE +202 -0
- data/CHANGELOG.md +28 -0
- data/CONTRIBUTORS.md +7 -0
- data/LICENSE +20 -0
- data/README.md +288 -0
- data/Rakefile +68 -0
- data/TODO.md +5 -0
- data/VERSION +1 -0
- data/examples/friendly.yml +7 -0
- data/friendly.gemspec +240 -0
- data/lib/friendly.rb +58 -0
- data/lib/friendly/associations.rb +7 -0
- data/lib/friendly/associations/association.rb +34 -0
- data/lib/friendly/associations/set.rb +37 -0
- data/lib/friendly/attribute.rb +98 -0
- data/lib/friendly/boolean.rb +10 -0
- data/lib/friendly/cache.rb +24 -0
- data/lib/friendly/cache/by_id.rb +33 -0
- data/lib/friendly/data_store.rb +73 -0
- data/lib/friendly/document.rb +70 -0
- data/lib/friendly/document/associations.rb +50 -0
- data/lib/friendly/document/attributes.rb +114 -0
- data/lib/friendly/document/convenience.rb +41 -0
- data/lib/friendly/document/mixin.rb +15 -0
- data/lib/friendly/document/scoping.rb +66 -0
- data/lib/friendly/document/storage.rb +63 -0
- data/lib/friendly/document_table.rb +56 -0
- data/lib/friendly/index.rb +73 -0
- data/lib/friendly/indexer.rb +50 -0
- data/lib/friendly/memcached.rb +48 -0
- data/lib/friendly/newrelic.rb +6 -0
- data/lib/friendly/query.rb +42 -0
- data/lib/friendly/scope.rb +100 -0
- data/lib/friendly/scope_proxy.rb +43 -0
- data/lib/friendly/sequel_monkey_patches.rb +34 -0
- data/lib/friendly/storage.rb +31 -0
- data/lib/friendly/storage_factory.rb +24 -0
- data/lib/friendly/storage_proxy.rb +111 -0
- data/lib/friendly/table.rb +15 -0
- data/lib/friendly/table_creator.rb +50 -0
- data/lib/friendly/time.rb +14 -0
- data/lib/friendly/translator.rb +33 -0
- data/lib/friendly/uuid.rb +148 -0
- data/lib/tasks/friendly.rake +7 -0
- data/rails/init.rb +3 -0
- data/spec/config.yml.example +7 -0
- data/spec/fakes/data_store_fake.rb +29 -0
- data/spec/fakes/database_fake.rb +12 -0
- data/spec/fakes/dataset_fake.rb +28 -0
- data/spec/fakes/document.rb +18 -0
- data/spec/fakes/serializer_fake.rb +12 -0
- data/spec/fakes/time_fake.rb +12 -0
- data/spec/integration/ad_hoc_scopes_spec.rb +42 -0
- data/spec/integration/basic_object_lifecycle_spec.rb +114 -0
- data/spec/integration/batch_insertion_spec.rb +29 -0
- data/spec/integration/convenience_api_spec.rb +25 -0
- data/spec/integration/count_spec.rb +12 -0
- data/spec/integration/default_value_spec.rb +30 -0
- data/spec/integration/dirty_tracking_spec.rb +43 -0
- data/spec/integration/find_via_cache_spec.rb +101 -0
- data/spec/integration/finder_spec.rb +71 -0
- data/spec/integration/has_many_spec.rb +18 -0
- data/spec/integration/index_spec.rb +57 -0
- data/spec/integration/named_scope_spec.rb +34 -0
- data/spec/integration/offline_indexing_spec.rb +53 -0
- data/spec/integration/pagination_spec.rb +63 -0
- data/spec/integration/scope_chaining_spec.rb +22 -0
- data/spec/integration/table_creator_spec.rb +69 -0
- data/spec/integration/write_through_cache_spec.rb +53 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +105 -0
- data/spec/unit/associations/association_spec.rb +57 -0
- data/spec/unit/associations/set_spec.rb +43 -0
- data/spec/unit/attribute_spec.rb +125 -0
- data/spec/unit/cache_by_id_spec.rb +102 -0
- data/spec/unit/cache_spec.rb +21 -0
- data/spec/unit/data_store_spec.rb +201 -0
- data/spec/unit/document/attributes_spec.rb +130 -0
- data/spec/unit/document_spec.rb +318 -0
- data/spec/unit/document_table_spec.rb +126 -0
- data/spec/unit/friendly_spec.rb +25 -0
- data/spec/unit/index_spec.rb +196 -0
- data/spec/unit/memcached_spec.rb +114 -0
- data/spec/unit/query_spec.rb +104 -0
- data/spec/unit/scope_proxy_spec.rb +44 -0
- data/spec/unit/scope_spec.rb +113 -0
- data/spec/unit/storage_factory_spec.rb +59 -0
- data/spec/unit/storage_proxy_spec.rb +244 -0
- data/spec/unit/translator_spec.rb +91 -0
- data/website/index.html +210 -0
- data/website/scripts/clipboard.swf +0 -0
- data/website/scripts/shBrushAS3.js +61 -0
- data/website/scripts/shBrushBash.js +66 -0
- data/website/scripts/shBrushCSharp.js +67 -0
- data/website/scripts/shBrushColdFusion.js +102 -0
- data/website/scripts/shBrushCpp.js +99 -0
- data/website/scripts/shBrushCss.js +93 -0
- data/website/scripts/shBrushDelphi.js +57 -0
- data/website/scripts/shBrushDiff.js +43 -0
- data/website/scripts/shBrushErlang.js +54 -0
- data/website/scripts/shBrushGroovy.js +69 -0
- data/website/scripts/shBrushJScript.js +52 -0
- data/website/scripts/shBrushJava.js +59 -0
- data/website/scripts/shBrushJavaFX.js +60 -0
- data/website/scripts/shBrushPerl.js +74 -0
- data/website/scripts/shBrushPhp.js +91 -0
- data/website/scripts/shBrushPlain.js +35 -0
- data/website/scripts/shBrushPowerShell.js +76 -0
- data/website/scripts/shBrushPython.js +66 -0
- data/website/scripts/shBrushRuby.js +57 -0
- data/website/scripts/shBrushScala.js +53 -0
- data/website/scripts/shBrushSql.js +68 -0
- data/website/scripts/shBrushVb.js +58 -0
- data/website/scripts/shBrushXml.js +71 -0
- data/website/scripts/shCore.js +30 -0
- data/website/scripts/shLegacy.js +30 -0
- data/website/styles/friendly.css +103 -0
- data/website/styles/help.png +0 -0
- data/website/styles/ie.css +35 -0
- data/website/styles/magnifier.png +0 -0
- data/website/styles/page_white_code.png +0 -0
- data/website/styles/page_white_copy.png +0 -0
- data/website/styles/print.css +29 -0
- data/website/styles/printer.png +0 -0
- data/website/styles/screen.css +257 -0
- data/website/styles/shCore.css +330 -0
- data/website/styles/shThemeDefault.css +173 -0
- data/website/styles/shThemeDjango.css +176 -0
- data/website/styles/shThemeEclipse.css +190 -0
- data/website/styles/shThemeEmacs.css +175 -0
- data/website/styles/shThemeFadeToGrey.css +177 -0
- data/website/styles/shThemeMidnight.css +175 -0
- data/website/styles/shThemeRDark.css +175 -0
- metadata +337 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Batch inserting several documents" do
|
|
4
|
+
it "inserts them when the block returns" do
|
|
5
|
+
Friendly.batch do
|
|
6
|
+
user = User.new(:name => "Lois")
|
|
7
|
+
user.save
|
|
8
|
+
User.all(:name => "Lois").should be_empty
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
User.all(:name => "Lois").should_not be_empty
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "doesn't insert anything if an error is raised" do
|
|
15
|
+
begin
|
|
16
|
+
Friendly.batch do
|
|
17
|
+
user = User.new(:name => "Meg")
|
|
18
|
+
user.save
|
|
19
|
+
raise "AHHHH!"
|
|
20
|
+
end
|
|
21
|
+
rescue RuntimeError => e
|
|
22
|
+
@bubbled_up = true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@bubbled_up.should be_true
|
|
26
|
+
|
|
27
|
+
User.all(:name => "Meg").should be_empty
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Document.create" do
|
|
4
|
+
before do
|
|
5
|
+
@user = User.create(:name => "James")
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "initializes the document, saves it, and returns it" do
|
|
9
|
+
@user.name.should == "James"
|
|
10
|
+
@user.should_not be_new_record
|
|
11
|
+
User.find(@user.id).should_not be_nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "Document#update_attributes" do
|
|
16
|
+
before do
|
|
17
|
+
@user = User.create
|
|
18
|
+
@user.update_attributes :name => "James"
|
|
19
|
+
@user = User.find(@user.id)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "updates the attributes in the database" do
|
|
23
|
+
@user.name.should == "James"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Counting the objects matching a query" do
|
|
4
|
+
before do
|
|
5
|
+
User.all(:name => "Evil Monkey").each { |u| u.destroy }
|
|
6
|
+
5.times { User.create :name => "Evil Monkey" }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "does a count in the index to find out what matches" do
|
|
10
|
+
User.count(:name => "Evil Monkey").should == 5
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "An attribute with a default value" do
|
|
4
|
+
describe "before saving" do
|
|
5
|
+
before do
|
|
6
|
+
@user = User.new
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "has the value by default" do
|
|
10
|
+
@user.happy.should be_true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "has a default vaue even when it's false" do
|
|
14
|
+
@user.sad.should be_false
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "after saving" do
|
|
19
|
+
before do
|
|
20
|
+
@user = User.new
|
|
21
|
+
@user.save
|
|
22
|
+
@user = User.find(@user.id)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "doesn't set the existing attributes as dirty" do
|
|
26
|
+
@user.should_not be_changed
|
|
27
|
+
@user.should_not be_happy_changed
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Changing an attribute" do
|
|
4
|
+
describe "before a record is saved" do
|
|
5
|
+
before do
|
|
6
|
+
@user = User.new
|
|
7
|
+
@user.name = "James"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "responds to the attribute being changed" do
|
|
11
|
+
@user.should be_name_changed
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "returns the original value of the attribute" do
|
|
15
|
+
@user.name_was.should == ""
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "is changed" do
|
|
19
|
+
@user.should be_changed
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "after saving a record with changed attributes" do
|
|
24
|
+
before do
|
|
25
|
+
@user = User.create
|
|
26
|
+
@user.name = "James"
|
|
27
|
+
@user.save
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "is no longer attribute_changed?" do
|
|
31
|
+
@user.should_not be_name_changed
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "returns nil for attribute_was" do
|
|
35
|
+
@user.name_was.should be_nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "is no longer changed" do
|
|
39
|
+
@user.should_not be_changed
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Finding objects in the cache" do
|
|
4
|
+
def cache_key(user)
|
|
5
|
+
["Address", 0, user.id.to_guid].join("/")
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe "by id" do
|
|
9
|
+
before do
|
|
10
|
+
@address = Address.create :street => "Spooner"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "if the user is in cache" do
|
|
14
|
+
before do
|
|
15
|
+
$cache.set(cache_key(@address), "the address")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "returns the object from cache if its there" do
|
|
19
|
+
Address.first(:id => @address.id).should == "the address"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "if the user isn't there" do
|
|
24
|
+
before do
|
|
25
|
+
$cache.delete(cache_key(@address))
|
|
26
|
+
@found = Address.first(:id => @address.id)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "finds the object in the database" do
|
|
30
|
+
@found.should == @address
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "stores the object in cache (read through)" do
|
|
34
|
+
$cache.get(cache_key(@address)).should == @address
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "several objects via id" do
|
|
40
|
+
before do
|
|
41
|
+
@addresses = (0..3).map { Address.create :street => "Spooner" }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "when all objects are found" do
|
|
45
|
+
before do
|
|
46
|
+
@addresses.each { |a| $cache.set(cache_key(a), "the address") }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "returns all the objects from cache" do
|
|
50
|
+
Address.all(:id => @addresses.map { |u| u.id }).should == ["the address"] * 4
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe "when some objects are missing" do
|
|
55
|
+
before do
|
|
56
|
+
$cache.delete(cache_key(@addresses.first))
|
|
57
|
+
@found = Address.all(:id => @addresses.map { |u| u.id })
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "finds the object and returns it" do
|
|
61
|
+
expected = @addresses.sort { |a,b| a.id <=> b.id }
|
|
62
|
+
@found.sort { |a,b| a.id <=> b.id }.should == expected
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "writes the object through to the cache" do
|
|
66
|
+
lambda {
|
|
67
|
+
$cache.get(cache_key(@addresses.first))
|
|
68
|
+
}.should_not raise_error
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "calling all when the array of ids is empty" do
|
|
74
|
+
it "returns nothing" do
|
|
75
|
+
Address.all(:id => [])
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe "finding several objects in order via cache" do
|
|
80
|
+
before do
|
|
81
|
+
@addresses = (0...5).map { Address.create :street => "Spooner" }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "returns them in order" do
|
|
85
|
+
fnd = Address.all(:id => @addresses.map { |a| a.id }, :preserve_order! => true)
|
|
86
|
+
fnd.should == @addresses
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "when there's an object in the index that doesn't really exist" do
|
|
91
|
+
before do
|
|
92
|
+
table = $db.from("index_addresses_on_street")
|
|
93
|
+
table.where(:street => "Quahog").delete
|
|
94
|
+
table.insert(:street => "Quahog", :id => "12345")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "just returns [] silently on #all" do
|
|
98
|
+
Address.all(:street => "Quahog").should == []
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
require 'active_support/duration'
|
|
3
|
+
require 'active_support/core_ext/integer'
|
|
4
|
+
require 'active_support/core_ext/time'
|
|
5
|
+
require 'active_support/core_ext/object'
|
|
6
|
+
require 'active_support/core_ext/numeric'
|
|
7
|
+
|
|
8
|
+
describe "Finding multiple objects by id" do
|
|
9
|
+
before do
|
|
10
|
+
@user_one = User.new
|
|
11
|
+
@user_two = User.new
|
|
12
|
+
@user_one.save
|
|
13
|
+
@user_two.save
|
|
14
|
+
@users = User.all(:id => [@user_one.id, @user_two.id])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "finds the objects in the database" do
|
|
18
|
+
@users.length.should == 2
|
|
19
|
+
@users.should include(@user_one)
|
|
20
|
+
@users.should include(@user_two)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "when no objects are found" do
|
|
24
|
+
it "returns an empty array" do
|
|
25
|
+
User.all(:id => [9999, 12345, 999]).should == []
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "when one object is found, but others aren't" do
|
|
30
|
+
it "returns the found objects" do
|
|
31
|
+
User.all(:id => [@user_one.id, 12345]).should == [@user_one]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "Limiting a query" do
|
|
37
|
+
before do
|
|
38
|
+
10.times { User.new(:name => "Stewie").save }
|
|
39
|
+
@results = User.all(:name => "Stewie", :limit! => 5)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "returns the number of results you asked for" do
|
|
43
|
+
@results.length.should == 5
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "limiting a query with offset" do
|
|
48
|
+
before do
|
|
49
|
+
@objects = (0..10).map do |i|
|
|
50
|
+
User.new(:name => "Joe", :created_at => i.minutes.from_now).tap do |u|
|
|
51
|
+
u.save
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
after { @objects.each { |o| o.destroy } }
|
|
57
|
+
|
|
58
|
+
it "returns results starting from the offset to hte limit" do
|
|
59
|
+
User.all(:name => "Joe",
|
|
60
|
+
:offset! => 2,
|
|
61
|
+
:limit! => 2,
|
|
62
|
+
:order! => :created_at.desc).should == @objects.reverse.slice(2, 2)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "all with only order" do
|
|
67
|
+
it "queries the index" do
|
|
68
|
+
Address.create
|
|
69
|
+
Address.all(:order! => :created_at.desc, :limit! => 5)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Has many associations" do
|
|
4
|
+
before do
|
|
5
|
+
@user = User.create :name => "Fred"
|
|
6
|
+
@addresses = (0..2).map { Address.create :user_id => @user.id }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "returns the objects whose foreign keys match the object's id" do
|
|
10
|
+
found = @user.addresses.all.sort { |a, b| a.id <=> b.id }
|
|
11
|
+
found.should == @addresses.sort { |a, b| a.id <=> b.id }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "accepts class_name and foreign_key overrides" do
|
|
15
|
+
found = @user.addresses_override.all.sort { |a, b| a.id <=> b.id }
|
|
16
|
+
found.should == @addresses.sort { |a, b| a.id <=> b.id }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
require 'active_support/duration'
|
|
3
|
+
require 'active_support/core_ext/integer'
|
|
4
|
+
require 'active_support/core_ext/time'
|
|
5
|
+
require 'active_support/core_ext/object'
|
|
6
|
+
require 'active_support/core_ext/numeric'
|
|
7
|
+
|
|
8
|
+
describe "Finding one object with an index" do
|
|
9
|
+
before do
|
|
10
|
+
@created_user = User.new(:name => "Cleveland")
|
|
11
|
+
@created_user.save
|
|
12
|
+
@found_user = User.first(:name => "Cleveland")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "finds the object" do
|
|
16
|
+
@found_user.should == @created_user
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "Finding one object that doesn't exist in the index" do
|
|
21
|
+
it "returns nil" do
|
|
22
|
+
User.first(:name => "asdf").should be_nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "Finding object on an index that doesn't exist" do
|
|
27
|
+
it "raises Friendly::MissingIndex" do
|
|
28
|
+
lambda {
|
|
29
|
+
User.first(:age => 3)
|
|
30
|
+
}.should raise_error(Friendly::MissingIndex)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "Finding ordered objects" do
|
|
35
|
+
before do
|
|
36
|
+
@three = User.new(:name => "Brian", :created_at => 4.hours.ago)
|
|
37
|
+
@two = User.new(:name => "Brian", :created_at => 2.hours.ago)
|
|
38
|
+
@one = User.new(:name => "Brian", :created_at => 5.minutes.ago)
|
|
39
|
+
[@one, @two, @three].each { |i| i.save }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
after do
|
|
43
|
+
[@one, @two, @three].each { |i| i.destroy }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "can return the objects in desc order" do
|
|
47
|
+
found_users = User.all(:name => "Brian", :order! => :created_at.desc)
|
|
48
|
+
found_users.should == [@one, @two, @three]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "can return the objects in asc order" do
|
|
52
|
+
found_users = User.all(:name => "Brian", :order! => :created_at.asc)
|
|
53
|
+
found_users.length.should == 3
|
|
54
|
+
found_users.should == [@three, @two, @one]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "named_scope" do
|
|
4
|
+
describe "calling a single named_scope" do
|
|
5
|
+
before do
|
|
6
|
+
User.all(:name => "Quagmire").each { |q| q.destroy }
|
|
7
|
+
5.times { User.create(:name => "Quagmire") }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "all" do
|
|
11
|
+
it "returns all objects matching the conditions" do
|
|
12
|
+
User.named_quagmire.all.should == User.all(:name => "Quagmire")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "accepts extra conditions" do
|
|
16
|
+
User.create(:name => "Fred")
|
|
17
|
+
found = User.named_quagmire.all(:name => "Fred")
|
|
18
|
+
found.should == User.all(:name => "Fred")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "first" do
|
|
23
|
+
it "returns the first object matching the conditions" do
|
|
24
|
+
User.named_quagmire.first.should == User.first(:name => "Quagmire")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "accepts extra conditions" do
|
|
28
|
+
User.create(:name => "Fred")
|
|
29
|
+
found = User.named_quagmire.first(:name => "Fred")
|
|
30
|
+
found.should == User.first(:name => "Fred")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
describe "Building an index offline" do
|
|
4
|
+
before do
|
|
5
|
+
$db.drop_table :awesome_things if $db.table_exists?(:awesome_things)
|
|
6
|
+
|
|
7
|
+
if $db.table_exists?(:index_awesome_things_on_name)
|
|
8
|
+
$db.drop_table :index_awesome_things_on_name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
@klass = Class.new do
|
|
12
|
+
def self.name; "AwesomeThing"; end
|
|
13
|
+
def self.table_name; "awesome_things"; end
|
|
14
|
+
|
|
15
|
+
include Friendly::Document
|
|
16
|
+
|
|
17
|
+
attribute :name, String
|
|
18
|
+
end
|
|
19
|
+
@klass.create_tables!
|
|
20
|
+
|
|
21
|
+
@jameses = [@klass.create(:name => "James"), @klass.create(:name => "James")]
|
|
22
|
+
|
|
23
|
+
@klass.indexes :name
|
|
24
|
+
@klass.create_tables!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "" do
|
|
28
|
+
before do
|
|
29
|
+
Friendly::Indexer.populate(@klass, :name)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "builds the missing index rows for all the rows in the doc table" do
|
|
33
|
+
@klass.all(:name => "James").should == @jameses
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "ignores records that are already in the index" do
|
|
37
|
+
lambda {
|
|
38
|
+
Friendly::Indexer.populate(@klass, :name)
|
|
39
|
+
}.should_not raise_error
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "with more than `Indexer.objects_per_iteration` objects" do
|
|
44
|
+
before do
|
|
45
|
+
Friendly::Indexer.objects_per_iteration = 1
|
|
46
|
+
Friendly::Indexer.populate(@klass, :name)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "builds the missing index rows for all the rows in the doc table" do
|
|
50
|
+
@klass.all(:name => "James").should == @jameses
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|