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 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 = "TODO"
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
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 2
4
- :patch: 4
4
+ :patch: 5
@@ -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 [String, Hash, Fixnum, Float].include?(value.class)
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 value
158
+ value.empty? ? nil : Time.parse(value)
142
159
  else
143
160
  klass.new value
144
161
  end
@@ -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.strftime("%Y/%m/%d %H:%M:%S +0000")
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 "update" do
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.3
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-04-16 00:00:00 -07:00
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: 2
90
- summary: TODO
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