yeti 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/yeti/context.rb +4 -1
- data/lib/yeti/editor.rb +28 -5
- data/lib/yeti/search.rb +27 -11
- data/lib/yeti/version.rb +1 -1
- data/lib/yeti.rb +2 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/matchers.rb +35 -0
- data/spec/yeti/context_spec.rb +42 -0
- data/spec/yeti/editor_spec.rb +91 -35
- data/spec/yeti/search_spec.rb +101 -0
- metadata +10 -4
data/lib/yeti/context.rb
CHANGED
@@ -4,12 +4,15 @@ module Yeti
|
|
4
4
|
attr_reader :id
|
5
5
|
end
|
6
6
|
|
7
|
+
delegate :id, to: :account, prefix: :account
|
8
|
+
|
7
9
|
def initialize(hash)
|
8
10
|
@given_account_id = hash.fetch(:account_id)
|
9
11
|
end
|
10
12
|
|
11
13
|
def account
|
12
|
-
@account ||= find_account_by_id
|
14
|
+
@account ||= find_account_by_id given_account_id if given_account_id
|
15
|
+
@account ||= no_account
|
13
16
|
end
|
14
17
|
|
15
18
|
def find_account_by_id(id)
|
data/lib/yeti/editor.rb
CHANGED
@@ -74,16 +74,27 @@ module Yeti
|
|
74
74
|
attr_reader :given_id
|
75
75
|
|
76
76
|
def self.attribute(name, opts={})
|
77
|
-
|
77
|
+
opts[:attribute_name] = name
|
78
|
+
opts[:from] = :edited unless opts.has_key? :from
|
79
|
+
attribute_options[name.to_sym] = opts
|
78
80
|
define_attribute_methods attributes
|
79
|
-
from = opts[:from]
|
81
|
+
from = case opts[:from].to_s
|
82
|
+
when "" then "nil"
|
83
|
+
when /^\./ then "self#{opts[:from]}"
|
84
|
+
when /\./ then opts[:from]
|
85
|
+
else "#{opts[:from]}.#{name}"
|
86
|
+
end
|
80
87
|
class_eval """
|
81
88
|
def #{name}
|
82
|
-
|
89
|
+
unless defined? @#{name}
|
90
|
+
opts = self.class.attribute_options[:#{name}]
|
91
|
+
@#{name} = format_input #{from}, opts
|
92
|
+
end
|
83
93
|
@#{name}
|
84
94
|
end
|
85
95
|
def #{name}=(value)
|
86
|
-
|
96
|
+
opts = self.class.attribute_options[:#{name}]
|
97
|
+
value = format_output value, opts
|
87
98
|
return if value==#{name}
|
88
99
|
#{name}_will_change!
|
89
100
|
@#{name} = value
|
@@ -94,7 +105,11 @@ module Yeti
|
|
94
105
|
end
|
95
106
|
|
96
107
|
def self.attributes
|
97
|
-
|
108
|
+
attribute_options.keys
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.attribute_options
|
112
|
+
@attribute_options ||= {}
|
98
113
|
end
|
99
114
|
|
100
115
|
def self.dont_translate_error_messages
|
@@ -105,5 +120,13 @@ module Yeti
|
|
105
120
|
!!@untranslated
|
106
121
|
end
|
107
122
|
|
123
|
+
def format_input(value, attribute_opts)
|
124
|
+
value.to_s if value
|
125
|
+
end
|
126
|
+
|
127
|
+
def format_output(value, attribute_opts)
|
128
|
+
value.to_s.clean.strip if value
|
129
|
+
end
|
130
|
+
|
108
131
|
end
|
109
132
|
end
|
data/lib/yeti/search.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
module Yeti
|
2
2
|
class Search
|
3
3
|
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
delegate :to_ary, :empty?, :each, :group_by, :size, to: :results
|
6
|
+
delegate :page_count, to: :paginated_results
|
6
7
|
|
7
8
|
def initialize(context, hash)
|
8
9
|
@context = context
|
9
|
-
@
|
10
|
-
@page = hash[:page] || 1
|
11
|
-
@per_page = hash[:per_page] || 20
|
10
|
+
@hash = hash
|
12
11
|
end
|
13
12
|
|
14
|
-
def
|
15
|
-
|
13
|
+
def search
|
14
|
+
@search ||= (hash[:search] || {}).with_indifferent_access
|
15
|
+
end
|
16
|
+
|
17
|
+
def page
|
18
|
+
@page ||= [1, (hash[:page] || 1).to_i].max
|
19
|
+
end
|
20
|
+
|
21
|
+
def per_page
|
22
|
+
@per_page ||= begin
|
23
|
+
per_page = [1, (hash[:per_page] || 20).to_i].max
|
24
|
+
max = self.class.max_per_page
|
25
|
+
max ? [per_page, max].min : per_page
|
26
|
+
end
|
16
27
|
end
|
17
28
|
|
18
29
|
def count
|
@@ -38,18 +49,23 @@ module Yeti
|
|
38
49
|
end
|
39
50
|
end
|
40
51
|
|
52
|
+
def paginated_results
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
41
56
|
private
|
42
57
|
|
43
|
-
attr_reader :
|
58
|
+
attr_reader :hash
|
59
|
+
|
60
|
+
# ~~~ private class methods ~~~
|
61
|
+
def self.max_per_page(value=nil)
|
62
|
+
value ? @max_per_page = value : @max_per_page
|
63
|
+
end
|
44
64
|
|
45
65
|
# ~~~ private instance methods ~~~
|
46
66
|
def delegate_to_search_pattern
|
47
67
|
/(?:_equals|_contains|_gte|_lte)\z/
|
48
68
|
end
|
49
69
|
|
50
|
-
def paginated_results
|
51
|
-
raise NotImplementedError
|
52
|
-
end
|
53
|
-
|
54
70
|
end
|
55
71
|
end
|
data/lib/yeti/version.rb
CHANGED
data/lib/yeti.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
RSpec::Matchers.define :delegates do |delegated_method|
|
2
|
+
match do |subject|
|
3
|
+
stubbed = send(@delegate).stub(@delegate_method)
|
4
|
+
stubbed.with @delegate_params if @delegate_params
|
5
|
+
stubbed.and_return expected=mock
|
6
|
+
subject.send(delegated_method) === expected
|
7
|
+
end
|
8
|
+
|
9
|
+
chain :to do |delegate|
|
10
|
+
if delegate.is_a?(String) && delegate.include?("#")
|
11
|
+
@delegate, @delegate_method = delegate.split "#"
|
12
|
+
else
|
13
|
+
@delegate = delegate
|
14
|
+
@delegate_method = delegated_method
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
chain :with do |delegate_params|
|
19
|
+
@delegate_params = delegate_params
|
20
|
+
end
|
21
|
+
|
22
|
+
description do
|
23
|
+
delegate_method = ("##{@delegate_method}" if delegated_method.to_s!=@delegate_method.to_s)
|
24
|
+
delegate_params = (" with params #{@delegate_params.inspect}" if @delegate_params)
|
25
|
+
"delegates #{delegated_method} to #{@delegate}#{delegate_method}#{delegate_params}"
|
26
|
+
end
|
27
|
+
|
28
|
+
failure_message_for_should do |text|
|
29
|
+
"expected delegation of #{delegated_method} to #{@delegate}"
|
30
|
+
end
|
31
|
+
|
32
|
+
failure_message_for_should do |text|
|
33
|
+
"do not expected delegation of #{delegated_method} to #{@delegate}"
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Yeti::Context do
|
4
|
+
context "initialization" do
|
5
|
+
it "requires a hash with account_id" do
|
6
|
+
lambda{ Yeti::Context.new }.should raise_error ArgumentError, "wrong number of arguments (0 for 1)"
|
7
|
+
lambda{ Yeti::Context.new key: nil }.should raise_error KeyError, "key not found: :account_id"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
context "when account_id is nil" do
|
11
|
+
subject{ Yeti::Context.new account_id: nil }
|
12
|
+
it "#account is an instance of Yeti::Context::NoAccount" do
|
13
|
+
subject.account.should be_kind_of Yeti::Context::NoAccount
|
14
|
+
end
|
15
|
+
it("#account_id is nil"){ subject.account_id.should be_nil }
|
16
|
+
it "no account can be overriden by subclasses" do
|
17
|
+
subclass = Class.new Yeti::Context do
|
18
|
+
def no_account
|
19
|
+
:custom_no_account
|
20
|
+
end
|
21
|
+
end
|
22
|
+
subject = subclass.new account_id: nil
|
23
|
+
subject.account.should == :custom_no_account
|
24
|
+
end
|
25
|
+
end
|
26
|
+
context "when account_id" do
|
27
|
+
subject{ Yeti::Context.new account_id: 1 }
|
28
|
+
it "uses find_account_by_id to find account" do
|
29
|
+
subject.stub(:find_account_by_id).with(1).and_return(expected = mock)
|
30
|
+
subject.account.should be expected
|
31
|
+
end
|
32
|
+
it "#find_account_by_id is virtual" do
|
33
|
+
lambda do
|
34
|
+
subject.find_account_by_id 1
|
35
|
+
end.should raise_error NotImplementedError
|
36
|
+
end
|
37
|
+
it "#account_id returns account.id" do
|
38
|
+
subject.stub(:find_account_by_id).with(1).and_return mock(id: 2)
|
39
|
+
subject.account_id.should be 2
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/yeti/editor_spec.rb
CHANGED
@@ -1,50 +1,50 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Yeti::Editor do
|
4
4
|
let(:context){ mock :context }
|
5
|
-
subject{
|
6
|
-
it "
|
5
|
+
subject{ Yeti::Editor.new context, nil }
|
6
|
+
it "keeps given context" do
|
7
7
|
subject.context.should be context
|
8
8
|
end
|
9
|
-
it "#find_by_id
|
9
|
+
it "#find_by_id is virtual" do
|
10
10
|
lambda{ subject.find_by_id 1 }.should raise_error NotImplementedError
|
11
11
|
end
|
12
|
-
it "#new_object
|
12
|
+
it "#new_object is virtual" do
|
13
13
|
lambda{ subject.new_object }.should raise_error NotImplementedError
|
14
14
|
end
|
15
|
-
it "#persist!
|
15
|
+
it "#persist! is virtual" do
|
16
16
|
lambda{ subject.persist! }.should raise_error NotImplementedError
|
17
17
|
end
|
18
18
|
context "with a given id" do
|
19
|
-
subject{
|
19
|
+
subject{ Yeti::Editor.new context, 1 }
|
20
20
|
it{ should be_persisted }
|
21
|
-
it "#
|
21
|
+
it "uses #find_by_id to find the main object being edited" do
|
22
22
|
subject.stub(:find_by_id).with(1).and_return(expected = mock)
|
23
23
|
subject.edited.should be expected
|
24
24
|
end
|
25
25
|
end
|
26
26
|
context "without id" do
|
27
27
|
it{ should_not be_persisted }
|
28
|
-
it "#
|
28
|
+
it "uses #new_object to initialize main object being edited" do
|
29
29
|
subject.stub(:new_object).and_return(expected = mock)
|
30
30
|
subject.edited.should be expected
|
31
31
|
end
|
32
32
|
end
|
33
33
|
context "when not valid" do
|
34
34
|
before{ subject.stub(:valid?).and_return false }
|
35
|
-
it "#save
|
35
|
+
it "#save returns false" do
|
36
36
|
subject.save.should be false
|
37
37
|
end
|
38
38
|
end
|
39
39
|
context "when valid" do
|
40
|
-
it "#save
|
40
|
+
it "#save calls persist! then returns true" do
|
41
41
|
subject.should_receive :persist!
|
42
42
|
subject.save.should be true
|
43
43
|
end
|
44
44
|
end
|
45
45
|
context "editor of one record" do
|
46
|
-
let :
|
47
|
-
Class.new
|
46
|
+
let :editor_class do
|
47
|
+
Class.new Yeti::Editor do
|
48
48
|
attribute :name
|
49
49
|
validates_presence_of :name
|
50
50
|
def self.name
|
@@ -53,45 +53,45 @@ describe ::Yeti::Editor do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
context "new record" do
|
56
|
-
subject{
|
56
|
+
subject{ editor_class.new context, nil }
|
57
57
|
let(:new_record){ mock :new_record, name: nil, id: nil }
|
58
58
|
before{ subject.stub(:new_object).and_return new_record }
|
59
59
|
its(:id){ should be_nil }
|
60
60
|
its(:name){ should be_nil }
|
61
|
-
it "#name=
|
61
|
+
it "#name= converts input to string" do
|
62
62
|
subject.name = ["test"]
|
63
63
|
subject.name.should == "[\"test\"]"
|
64
64
|
end
|
65
|
-
it "#name=
|
65
|
+
it "#name= cleans the value of any harmful content" do
|
66
66
|
subject.name = "\tInfected\210\004"
|
67
67
|
subject.name.should == "Infected"
|
68
68
|
end
|
69
|
-
it "#name=
|
69
|
+
it "#name= accepts nil" do
|
70
70
|
subject.name = "Valid"
|
71
71
|
subject.name = nil
|
72
72
|
subject.name.should be_nil
|
73
73
|
end
|
74
|
-
it "#attributes
|
74
|
+
it "#attributes returns a hash" do
|
75
75
|
subject.attributes.should == {name: nil}
|
76
76
|
end
|
77
|
-
it "#attributes=
|
77
|
+
it "#attributes= assigns each attribute" do
|
78
78
|
subject.should_receive(:name=).with "Anthony"
|
79
79
|
subject.attributes = {name: "Anthony"}
|
80
80
|
end
|
81
|
-
it "#attributes=
|
81
|
+
it "#attributes= skips unknown attributes" do
|
82
82
|
subject.attributes = {unknown: "Anthony"}
|
83
83
|
end
|
84
84
|
context "before validation" do
|
85
85
|
its(:errors){ should be_empty }
|
86
86
|
end
|
87
87
|
context "after validation" do
|
88
|
-
it "
|
88
|
+
it "has an error on name" do
|
89
89
|
subject.valid?
|
90
90
|
subject.errors[:name].should have(1).item
|
91
91
|
subject.errors[:name].should == ["can't be blank"]
|
92
92
|
end
|
93
|
-
it "
|
94
|
-
|
93
|
+
it "can return untranslated error messages" do
|
94
|
+
editor_class.class_eval do
|
95
95
|
dont_translate_error_messages
|
96
96
|
end
|
97
97
|
subject.valid?
|
@@ -104,12 +104,12 @@ describe ::Yeti::Editor do
|
|
104
104
|
context "when name is changed" do
|
105
105
|
before{ subject.name = "Anthony" }
|
106
106
|
it{ should be_valid }
|
107
|
-
it "#attributes
|
107
|
+
it "#attributes is updated" do
|
108
108
|
subject.attributes.should == {name: "Anthony"}
|
109
109
|
end
|
110
|
-
it("name
|
111
|
-
it("name
|
112
|
-
it "name
|
110
|
+
it("name is updated"){ subject.name.should == "Anthony" }
|
111
|
+
it("name is dirty"){ subject.name_changed?.should be true }
|
112
|
+
it "name isn't dirty anymore if original value is set back" do
|
113
113
|
subject.name = nil
|
114
114
|
subject.name_changed?.should be false
|
115
115
|
end
|
@@ -120,32 +120,88 @@ describe ::Yeti::Editor do
|
|
120
120
|
subject.stub :persist!
|
121
121
|
subject.save
|
122
122
|
end
|
123
|
-
it "
|
123
|
+
it "resets dirty attributes" do
|
124
124
|
subject.name_changed?.should be false
|
125
125
|
end
|
126
|
-
it "
|
126
|
+
it "still knows previous changes" do
|
127
127
|
subject.previous_changes.should == {"name"=>[nil, "Anthony"]}
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
131
131
|
context "existing record" do
|
132
|
-
subject{
|
132
|
+
subject{ editor_class.new context, 1 }
|
133
133
|
let(:existing_record){ mock :existing_record, name: "Anthony", id: 1 }
|
134
134
|
before{ subject.stub(:find_by_id).with(1).and_return existing_record }
|
135
|
-
it("
|
136
|
-
it "
|
135
|
+
it("gets id from record"){ subject.id.should be 1 }
|
136
|
+
it "gets name from record" do
|
137
137
|
subject.name.should == "Anthony"
|
138
138
|
end
|
139
139
|
it{ should be_valid }
|
140
|
+
it "input formatting can be customized" do
|
141
|
+
subject.stub(:format_input).with("Anthony", {
|
142
|
+
attribute_name: :name,
|
143
|
+
from: :edited,
|
144
|
+
}).and_return(expected = mock)
|
145
|
+
subject.name.should be expected
|
146
|
+
end
|
147
|
+
it "output formatting can be customized" do
|
148
|
+
subject.stub(:format_output).with("Tony", {
|
149
|
+
attribute_name: :name,
|
150
|
+
from: :edited,
|
151
|
+
}).and_return(expected = mock)
|
152
|
+
subject.name = "Tony"
|
153
|
+
subject.name.should be expected
|
154
|
+
end
|
140
155
|
context "when name is changed" do
|
141
156
|
before{ subject.name = nil }
|
142
|
-
it("name
|
143
|
-
it("name
|
144
|
-
it "name
|
157
|
+
it("name is updated"){ subject.name.should be_nil }
|
158
|
+
it("name is dirty"){ subject.name_changed?.should be true }
|
159
|
+
it "name isn't dirty anymore if original value is set back" do
|
145
160
|
subject.name = "Anthony"
|
146
161
|
subject.name_changed?.should be false
|
147
162
|
end
|
148
163
|
end
|
149
164
|
end
|
150
165
|
end
|
166
|
+
context "editor of multiple records" do
|
167
|
+
let :editor_class do
|
168
|
+
Class.new Yeti::Editor do
|
169
|
+
attribute :name
|
170
|
+
attribute :description, from: :related
|
171
|
+
attribute :password, from: nil
|
172
|
+
attribute :timestamp, from: ".timestamp_str"
|
173
|
+
attribute :related_id, from: "related.id"
|
174
|
+
attribute :invalid
|
175
|
+
def find_by_id(id)
|
176
|
+
Struct.new(:id, :name).new(id, "Anthony")
|
177
|
+
end
|
178
|
+
def related
|
179
|
+
Struct.new(:id, :description).new 2, "Business man"
|
180
|
+
end
|
181
|
+
def timestamp_str
|
182
|
+
"2001-01-01"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
subject{ editor_class.new context, 1 }
|
187
|
+
it "attribute default value comes from edited" do
|
188
|
+
subject.id.should == 1
|
189
|
+
subject.name.should == "Anthony"
|
190
|
+
end
|
191
|
+
it "attribute value can come from another object" do
|
192
|
+
subject.description.should == "Business man"
|
193
|
+
end
|
194
|
+
it "attribute value can come from nowhere" do
|
195
|
+
subject.password.should be_nil
|
196
|
+
end
|
197
|
+
it "attribute value can come from specified method on self" do
|
198
|
+
subject.timestamp.should == "2001-01-01"
|
199
|
+
end
|
200
|
+
it "attribute value can come from specified method on another object" do
|
201
|
+
subject.related_id.should == "2"
|
202
|
+
end
|
203
|
+
it "attribute raises if value cannot be found in source" do
|
204
|
+
lambda{ subject.invalid }.should raise_error NoMethodError
|
205
|
+
end
|
206
|
+
end
|
151
207
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Yeti::Search do
|
4
|
+
let(:context){ mock :context }
|
5
|
+
context "initialization" do
|
6
|
+
it "does require a context and a hash" do
|
7
|
+
message = "wrong number of arguments (1 for 2)"
|
8
|
+
lambda do
|
9
|
+
Yeti::Search.new context
|
10
|
+
end.should raise_error ArgumentError, message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
context "given context and an empty hash" do
|
14
|
+
subject{ Yeti::Search.new context, {} }
|
15
|
+
it "keeps given context" do
|
16
|
+
subject.context.should be context
|
17
|
+
end
|
18
|
+
it "#search defaults to {}" do
|
19
|
+
subject.search.should == {}
|
20
|
+
end
|
21
|
+
it "#page defaults to 1" do
|
22
|
+
subject.page.should == 1
|
23
|
+
end
|
24
|
+
it "#per_page defaults to 20" do
|
25
|
+
subject.per_page.should == 20
|
26
|
+
end
|
27
|
+
end
|
28
|
+
context "given context and params" do
|
29
|
+
let :search do
|
30
|
+
{
|
31
|
+
"name_contains" => "tony",
|
32
|
+
"popular_equals" => "1",
|
33
|
+
"created_at_gte" => "2001-01-01",
|
34
|
+
"created_at_lte" => "2002-01-01",
|
35
|
+
"uncommon_filter" => "1",
|
36
|
+
}
|
37
|
+
end
|
38
|
+
let(:results){ mock :results }
|
39
|
+
subject{ Yeti::Search.new context, search: search }
|
40
|
+
before{ subject.stub(:results).and_return results }
|
41
|
+
it "#search comes from hash" do
|
42
|
+
subject.search.should == search
|
43
|
+
end
|
44
|
+
it "gets common filters from search" do
|
45
|
+
subject.should respond_to(:name_contains)
|
46
|
+
subject.should respond_to(:popular_equals)
|
47
|
+
subject.should respond_to(:created_at_gte)
|
48
|
+
subject.should respond_to(:created_at_lte)
|
49
|
+
subject.name_contains.should == "tony"
|
50
|
+
subject.popular_equals.should == "1"
|
51
|
+
subject.created_at_gte.should == "2001-01-01"
|
52
|
+
subject.created_at_lte.should == "2002-01-01"
|
53
|
+
end
|
54
|
+
it "doesn't get everything from search" do
|
55
|
+
subject.should_not respond_to(:uncommon_filter)
|
56
|
+
lambda{ subject.invalid_method }.should raise_error NoMethodError
|
57
|
+
lambda{ subject.uncommon_filter }.should raise_error NoMethodError
|
58
|
+
end
|
59
|
+
it "#page comes from hash" do
|
60
|
+
Yeti::Search.new(context, page: "2").page.should be 2
|
61
|
+
end
|
62
|
+
it "doesn't accept page to be lower than 1" do
|
63
|
+
Yeti::Search.new(context, page: "0").page.should be 1
|
64
|
+
end
|
65
|
+
it "#per_page comes from hash" do
|
66
|
+
Yeti::Search.new(context, per_page: "10").per_page.should be 10
|
67
|
+
end
|
68
|
+
it "doesn't accept per_page to be lower than 1" do
|
69
|
+
Yeti::Search.new(context, per_page: "0").per_page.should be 1
|
70
|
+
end
|
71
|
+
it "by default per_page has no limit" do
|
72
|
+
Yeti::Search.max_per_page.should be_nil
|
73
|
+
Yeti::Search.new(context, per_page: "9999").per_page.should be 9999
|
74
|
+
end
|
75
|
+
it "per_page can be limited" do
|
76
|
+
search_class = Class.new Yeti::Search do
|
77
|
+
max_per_page 50
|
78
|
+
end
|
79
|
+
search_class.max_per_page.should be 50
|
80
|
+
search_class.new(context, per_page: "9999").per_page.should be 50
|
81
|
+
end
|
82
|
+
it "#paginated_results is virtual" do
|
83
|
+
lambda do
|
84
|
+
subject.paginated_results
|
85
|
+
end.should raise_error NotImplementedError
|
86
|
+
end
|
87
|
+
it{ should delegates(:to_ary).to :results }
|
88
|
+
it{ should delegates(:empty?).to :results }
|
89
|
+
it{ should delegates(:each).to :results }
|
90
|
+
it{ should delegates(:group_by).to :results }
|
91
|
+
it{ should delegates(:size).to :results }
|
92
|
+
end
|
93
|
+
context "when paginated_results is defined" do
|
94
|
+
let(:paginated_results){ mock :paginated_results }
|
95
|
+
subject{ Yeti::Search.new context, {} }
|
96
|
+
before{ subject.stub(:paginated_results).and_return paginated_results }
|
97
|
+
it{ should delegates(:page_count).to :paginated_results }
|
98
|
+
it{ should delegates(:count).to "paginated_results#pagination_record_count" }
|
99
|
+
it{ should delegates(:results).to "paginated_results#all" }
|
100
|
+
end
|
101
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yeti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -94,7 +94,10 @@ files:
|
|
94
94
|
- lib/yeti/search.rb
|
95
95
|
- lib/yeti/version.rb
|
96
96
|
- spec/spec_helper.rb
|
97
|
+
- spec/support/matchers.rb
|
98
|
+
- spec/yeti/context_spec.rb
|
97
99
|
- spec/yeti/editor_spec.rb
|
100
|
+
- spec/yeti/search_spec.rb
|
98
101
|
- spec/yeti_spec.rb
|
99
102
|
- yeti.gemspec
|
100
103
|
homepage: ''
|
@@ -111,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
114
|
version: '0'
|
112
115
|
segments:
|
113
116
|
- 0
|
114
|
-
hash:
|
117
|
+
hash: -488456883026859265
|
115
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
119
|
none: false
|
117
120
|
requirements:
|
@@ -120,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
123
|
version: '0'
|
121
124
|
segments:
|
122
125
|
- 0
|
123
|
-
hash:
|
126
|
+
hash: -488456883026859265
|
124
127
|
requirements: []
|
125
128
|
rubyforge_project:
|
126
129
|
rubygems_version: 1.8.24
|
@@ -129,5 +132,8 @@ specification_version: 3
|
|
129
132
|
summary: Editor pattern simplifies edition of multiple objects at once using ActiveModel
|
130
133
|
test_files:
|
131
134
|
- spec/spec_helper.rb
|
135
|
+
- spec/support/matchers.rb
|
136
|
+
- spec/yeti/context_spec.rb
|
132
137
|
- spec/yeti/editor_spec.rb
|
138
|
+
- spec/yeti/search_spec.rb
|
133
139
|
- spec/yeti_spec.rb
|