mattly-exegesis 0.2.3 → 0.2.5
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/Rakefile +1 -1
- data/VERSION.yml +1 -1
- data/lib/exegesis/model.rb +22 -5
- data/lib/monkeypatches/time.rb +4 -1
- data/test/model_test.rb +21 -1
- data/test/view_option_parsing_test.rb +70 -0
- metadata +6 -4
data/Rakefile
CHANGED
|
@@ -6,7 +6,7 @@ begin
|
|
|
6
6
|
require 'jeweler'
|
|
7
7
|
Jeweler::Tasks.new do |s|
|
|
8
8
|
s.name = "exegesis"
|
|
9
|
-
s.summary = "
|
|
9
|
+
s.summary = "A Document <> Object Mapper for CouchDB Documents"
|
|
10
10
|
s.email = "matt@flowerpowered.com"
|
|
11
11
|
s.homepage = "http://github.com/mattly/exegesis"
|
|
12
12
|
s.description = "A Document <> Object Mapper for CouchDB Documents"
|
data/VERSION.yml
CHANGED
data/lib/exegesis/model.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module Exegesis
|
|
2
2
|
module Model
|
|
3
3
|
|
|
4
|
+
JSON_PRIMITIVES = [Array, String, Hash, Fixnum, Float]
|
|
5
|
+
|
|
4
6
|
def self.included base
|
|
5
7
|
base.extend ClassMethods
|
|
6
8
|
base.send :include, InstanceMethods
|
|
@@ -23,6 +25,7 @@ module Exegesis
|
|
|
23
25
|
define_reference_writer attrib unless opts[:writer] == false
|
|
24
26
|
elsif opts[:as]
|
|
25
27
|
define_caster attrib, opts[:as]
|
|
28
|
+
define_caster_writer attrib, opts[:as] unless opts[:writer] == false
|
|
26
29
|
else
|
|
27
30
|
define_method(attrib) { @attributes[attrib] }
|
|
28
31
|
end
|
|
@@ -33,10 +36,10 @@ module Exegesis
|
|
|
33
36
|
# else retrieves the default
|
|
34
37
|
def default hash=nil
|
|
35
38
|
if hash
|
|
36
|
-
@default
|
|
39
|
+
@default || default
|
|
37
40
|
hash.each {|key, value| @default[key.to_s] = value }
|
|
38
41
|
else
|
|
39
|
-
@default ||= {}
|
|
42
|
+
@default ||= superclass.respond_to?(:default) ? superclass.default.dup : {}
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
|
|
@@ -79,7 +82,20 @@ module Exegesis
|
|
|
79
82
|
end
|
|
80
83
|
end
|
|
81
84
|
end
|
|
82
|
-
|
|
85
|
+
|
|
86
|
+
def define_caster_writer attrib, as
|
|
87
|
+
define_writer(attrib) do |val|
|
|
88
|
+
@attributes[attrib] = if JSON_PRIMITIVES.include?(val.class)
|
|
89
|
+
if val.is_a?(Array)
|
|
90
|
+
val.map {|v| cast(as, v) }
|
|
91
|
+
else
|
|
92
|
+
cast(as, val)
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
val
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
83
99
|
end
|
|
84
100
|
|
|
85
101
|
module InstanceMethods
|
|
@@ -97,6 +113,7 @@ module Exegesis
|
|
|
97
113
|
# update the attributes in the model using writers. If no writer is defined for a given
|
|
98
114
|
# key it will raise NoMethodError
|
|
99
115
|
def update_attributes hash={}
|
|
116
|
+
hash.delete('class')
|
|
100
117
|
hash.each do |key, value|
|
|
101
118
|
self.send("#{key}=", value)
|
|
102
119
|
end
|
|
@@ -126,7 +143,7 @@ module Exegesis
|
|
|
126
143
|
|
|
127
144
|
def cast as, value
|
|
128
145
|
return nil if value.nil?
|
|
129
|
-
return value unless
|
|
146
|
+
return value unless JSON_PRIMITIVES.include?(value.class)
|
|
130
147
|
klass = if as == :given && value.is_a?(Hash)
|
|
131
148
|
Exegesis.constantize(value['class'])
|
|
132
149
|
elsif as.is_a?(Class)
|
|
@@ -138,7 +155,7 @@ module Exegesis
|
|
|
138
155
|
casted = if klass.nil?
|
|
139
156
|
value # if no class, just return the value
|
|
140
157
|
elsif klass == Time # Time is a special case; the ONLY special case.
|
|
141
|
-
Time.parse
|
|
158
|
+
value.empty? ? nil : Time.parse(value)
|
|
142
159
|
else
|
|
143
160
|
klass.new value
|
|
144
161
|
end
|
data/lib/monkeypatches/time.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
class Time
|
|
2
|
+
# returns the time, in UTC, in iso8601 format; see http://en.wikipedia.org/wiki/ISO_8601 for more details on this format
|
|
3
|
+
# One major advantage of this format over others is that it sorts lexigraphically, so if you want f.e. just stuff from
|
|
4
|
+
# April 2009 you may specify '2009-04'..'2009-04Z' as your key
|
|
2
5
|
def to_json_format
|
|
3
|
-
self.getutc.
|
|
6
|
+
self.getutc.iso8601
|
|
4
7
|
end
|
|
5
8
|
|
|
6
9
|
def to_json(options = nil)
|
data/test/model_test.rb
CHANGED
|
@@ -143,6 +143,18 @@ describe Exegesis::Model do
|
|
|
143
143
|
end
|
|
144
144
|
expect { @obj.time.must_equal @time }
|
|
145
145
|
expect { @obj.times.map{|time| time.localtime }.must_equal [@time, @time] }
|
|
146
|
+
expect { @obj['time'].must_equal @time }
|
|
147
|
+
expect { @obj['times'].must_equal [@time, @time] }
|
|
148
|
+
end
|
|
149
|
+
describe "from a blank string" do
|
|
150
|
+
before do
|
|
151
|
+
@obj.time = ''
|
|
152
|
+
@obj.times = ['', '']
|
|
153
|
+
end
|
|
154
|
+
expect { @obj.time.must_be_nil }
|
|
155
|
+
expect { @obj.times.map{|t| t }.must_equal [] }
|
|
156
|
+
expect { @obj['time'].must_be_nil }
|
|
157
|
+
expect { @obj['times'].must_equal [nil, nil] }
|
|
146
158
|
end
|
|
147
159
|
end
|
|
148
160
|
end
|
|
@@ -283,7 +295,7 @@ describe Exegesis::Model do
|
|
|
283
295
|
expect { @obj.read_only.must_equal 'bee' }
|
|
284
296
|
end
|
|
285
297
|
|
|
286
|
-
describe "
|
|
298
|
+
describe "update_attributes" do
|
|
287
299
|
describe "with a writer" do
|
|
288
300
|
before do
|
|
289
301
|
@obj.update_attributes(:foo => 'foo')
|
|
@@ -295,6 +307,14 @@ describe Exegesis::Model do
|
|
|
295
307
|
describe "without a writer" do
|
|
296
308
|
expect { lambda{@obj.update_attributes({:read_only => 'bee'})}.must_raise NoMethodError }
|
|
297
309
|
end
|
|
310
|
+
|
|
311
|
+
describe "with a 'class' key" do
|
|
312
|
+
before do
|
|
313
|
+
@obj.update_attributes('class' => 'Foo')
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
expect { @obj['class'].must_equal 'ExposeTestModel' }
|
|
317
|
+
end
|
|
298
318
|
end
|
|
299
319
|
end
|
|
300
320
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
|
2
|
+
|
|
3
|
+
class ViewOptionsParsingTestDatabase
|
|
4
|
+
include Exegesis::Database
|
|
5
|
+
|
|
6
|
+
designs_directory "test/fixtures/designs"
|
|
7
|
+
|
|
8
|
+
design :things do
|
|
9
|
+
view :by_name
|
|
10
|
+
docs :by_tag
|
|
11
|
+
hash :count, :view => :by_tag
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "parsing query options" do
|
|
16
|
+
before { @db = reset_db('', ViewOptionsParsingTestDatabase) }
|
|
17
|
+
|
|
18
|
+
describe "with a key as an initial arguemnt" do
|
|
19
|
+
expect { @db.things.parse_opts('foo').must_equal({:key => 'foo'}) }
|
|
20
|
+
expect { @db.things.parse_opts('foo', :include_docs => true).must_equal({:key => 'foo', :include_docs => true}) }
|
|
21
|
+
expect { @db.things.parse_opts('foo', {:stale => 'ok'}, {:include_docs => true}).must_equal({:key => 'foo', :stale => 'ok', :include_docs => true })}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "without an implied key" do
|
|
25
|
+
expect { @db.things.parse_opts(:key => 'foo').must_equal({:key => 'foo'}) }
|
|
26
|
+
expect { @db.things.parse_opts({:key => 'foo'}, nil, {:stale => 'ok'}).must_equal({:key => 'foo', :stale => 'ok'}) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "when a keys option is empty" do
|
|
30
|
+
expect { @db.things.parse_opts(:keys => []).must_equal({}) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "for ranges" do
|
|
34
|
+
describe "when the key _is_ a range" do
|
|
35
|
+
before { @opts = @db.things.parse_opts(:key => 'bar'..'baz') }
|
|
36
|
+
expect { @opts.has_key?(:key).must_equal false }
|
|
37
|
+
expect { @opts[:startkey].must_equal 'bar' }
|
|
38
|
+
expect { @opts[:endkey].must_equal 'baz'}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "when the key is an array that includes a range" do
|
|
42
|
+
before { @opts = @db.things.parse_opts(:key => ['published', '2009'..'2009/04']) }
|
|
43
|
+
expect { @opts.has_key?(:key).must_equal false }
|
|
44
|
+
expect { @opts[:startkey].must_equal ['published', '2009'] }
|
|
45
|
+
expect { @opts[:endkey].must_equal ['published', '2009/04'] }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "for non inclusive ranges" do
|
|
49
|
+
end
|
|
50
|
+
describe "when descending:true is an option" do
|
|
51
|
+
describe "and first value is greater than the end value" do
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
describe "when the first value is greater than the end value" do
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "invalid option configurations" do
|
|
58
|
+
expect { lambda {@db.things.parse_opts(:startkey => 'foo')}.must_raise ArgumentError }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "reducing" do
|
|
63
|
+
before { @parsing = lambda{|opts| @db.things.parse_opts(opts) } }
|
|
64
|
+
expect { @parsing.call(:group => 3).must_equal({:group_level => 3})}
|
|
65
|
+
expect { lambda{@parsing.call(:group => true, :reduce => false)}.must_raise ArgumentError }
|
|
66
|
+
expect { lambda{@parsing.call(:group => true, :include_docs => true)}.must_raise ArgumentError }
|
|
67
|
+
expect { lambda{@parsing.call(:group => 1, :reduce => false)}.must_raise ArgumentError }
|
|
68
|
+
expect { lambda{@parsing.call(:group => 1, :include_docs => true)}.must_raise ArgumentError }
|
|
69
|
+
end
|
|
70
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mattly-exegesis
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matt Lyon
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-
|
|
12
|
+
date: 2009-05-03 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
@@ -62,6 +62,7 @@ files:
|
|
|
62
62
|
- test/model_test.rb
|
|
63
63
|
- test/server_test.rb
|
|
64
64
|
- test/test_helper.rb
|
|
65
|
+
- test/view_option_parsing_test.rb
|
|
65
66
|
has_rdoc: true
|
|
66
67
|
homepage: http://github.com/mattly/exegesis
|
|
67
68
|
post_install_message:
|
|
@@ -86,8 +87,8 @@ requirements: []
|
|
|
86
87
|
rubyforge_project:
|
|
87
88
|
rubygems_version: 1.2.0
|
|
88
89
|
signing_key:
|
|
89
|
-
specification_version:
|
|
90
|
-
summary:
|
|
90
|
+
specification_version: 3
|
|
91
|
+
summary: A Document <> Object Mapper for CouchDB Documents
|
|
91
92
|
test_files:
|
|
92
93
|
- test/attachments_test.rb
|
|
93
94
|
- test/database_test.rb
|
|
@@ -98,3 +99,4 @@ test_files:
|
|
|
98
99
|
- test/model_test.rb
|
|
99
100
|
- test/server_test.rb
|
|
100
101
|
- test/test_helper.rb
|
|
102
|
+
- test/view_option_parsing_test.rb
|