yeti 0.1.0 → 0.1.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/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
|