frenchy 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65e1a3deb604054b63aafdf5bb1b5a565485a684
4
- data.tar.gz: bf9c15219f6fa720530a1598b7adc27ef9242baf
3
+ metadata.gz: bbd873ca7bf47ce23e6e60450167777221a970c4
4
+ data.tar.gz: b482ca20c727d4ebad679da013405e15e260bd37
5
5
  SHA512:
6
- metadata.gz: a97314440955f6d4a7048997c4309e65d95c6d5fa0207d5b01060178cadc51fded78c96d5d8e8db1c8beb199cf976a1d28f9770e33090eb9e6bddc219742b928
7
- data.tar.gz: 9f138c7b0812c883307475f06b7c0fd47f51e62602183d5706db3b802aad3c9318571b7ba6eba5e934f9dba297eaad7ded6b2c0c753b115441bb65b881f1115f
6
+ metadata.gz: e477ae25b9c358cf9ad06d3b1816720ef0da7b81666cda78c0780d9275dd9fabb8592b492a2a251e1e54ed49e8b1146606e431aedae18f42b688f4e9e246116c
7
+ data.tar.gz: aa04396f718b9523f060e6d29913c2c8601466f580fa9de1855bd6e3f0067d9d6c8f9dd69372edae0b21e01c83fea219065f27b4dbf5f26f3368e112118bd713
data/.travis.yml CHANGED
@@ -1,4 +1,3 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
4
- - 2.1.2
3
+ - 2.3.0
@@ -106,6 +106,9 @@ module Frenchy
106
106
  rescue => ex
107
107
  raise Frenchy::InvalidResponse.new(ex, reqinfo, resp)
108
108
  end
109
+ when 400
110
+ # Explicitly handle bad request errors
111
+ raise Frenchy::BadRequest.new(nil, reqinfo, resp)
109
112
  when 404
110
113
  # Explicitly handle not found errors
111
114
  raise Frenchy::NotFound.new(nil, reqinfo, resp)
data/lib/frenchy/error.rb CHANGED
@@ -24,6 +24,7 @@ module Frenchy
24
24
  end
25
25
  end
26
26
 
27
+ class BadRequest < RequestError; end
27
28
  class NotFound < RequestError; end
28
29
  class InvalidResponse < RequestError; end
29
30
  class ServerError < RequestError; end
data/lib/frenchy/model.rb CHANGED
@@ -7,7 +7,6 @@ module Frenchy
7
7
  self.fields = {}
8
8
  self.defaults = {}
9
9
  end
10
-
11
10
  end
12
11
 
13
12
  # Create a new instance of this model with the given attributes
@@ -54,7 +53,6 @@ module Frenchy
54
53
  end
55
54
 
56
55
  module ClassMethods
57
-
58
56
  # Class accessors
59
57
  def fields; @fields; end
60
58
  def defaults; @defaults; end
@@ -70,6 +68,21 @@ module Frenchy
70
68
  end
71
69
  end
72
70
 
71
+ # Macro to create a subtype
72
+ def type(name, &block)
73
+ klass = Class.new(self) do
74
+ include Frenchy::Model
75
+ end
76
+ const_set(name.to_s.camelize, klass)
77
+ klass.class_eval(&block)
78
+ end
79
+
80
+ # Macro to create a subtype and associated field
81
+ def embed(name, options={}, &block)
82
+ type(name, &block)
83
+ field(name, options.merge({type: name}))
84
+ end
85
+
73
86
  # Macro to add a field
74
87
  def field(name, options={})
75
88
  name = name.to_s
@@ -120,6 +133,10 @@ module Frenchy
120
133
  define_method("#{name}=") do |v|
121
134
  if v.is_a?(Fixnum)
122
135
  set(name, Time.at(v).to_datetime)
136
+ elsif v.is_a?(DateTime)
137
+ set(name, v)
138
+ elsif v.is_a?(Time)
139
+ set(name, v.to_datetime)
123
140
  else
124
141
  set(name, DateTime.parse(v))
125
142
  end
@@ -146,7 +163,7 @@ module Frenchy
146
163
  else
147
164
  # Unknown types have their type constantized and initialized with the value. This
148
165
  # allows us to support things like other Frenchy::Model classes, ActiveRecord models, etc.
149
- klass = (options["class_name"] || type.camelize).constantize
166
+ klass = const_get(options["class_name"] || type.camelize)
150
167
 
151
168
  # Fields with many values have a default of [] (unless previously set above)
152
169
  if options["many"]
@@ -1,3 +1,3 @@
1
1
  module Frenchy
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -23,6 +23,21 @@ end
23
23
  class Box
24
24
  include Frenchy::Model
25
25
 
26
+ class SubclassItem
27
+ include Frenchy::Model
28
+
29
+ field :id, type: "integer"
30
+ end
31
+
32
+ type :subtype_item do
33
+ field :id, type: "integer"
34
+ end
35
+
36
+ embed :child do
37
+ field :id, type: "integer"
38
+ field :name, type: "string"
39
+ end
40
+
26
41
  key :name
27
42
 
28
43
  field :id, type: "integer"
@@ -36,6 +51,8 @@ class Box
36
51
  field :item, type: "special_item"
37
52
  field :items, type: "special_item", many: true
38
53
  field :special, type: "special_item", class_name: "SuperSpecialItem"
54
+ field :subclass, type: "subclass_item"
55
+ field :subtype, type: "subtype_item"
39
56
  end
40
57
 
41
58
  class SimpleModelDecorator
@@ -149,6 +166,22 @@ describe Frenchy::Model do
149
166
  end
150
167
 
151
168
  describe "time" do
169
+ it "retains DateTime" do
170
+ t = DateTime.now
171
+ v = Box.new(birth: t).birth
172
+ expect(v.class).to eql(DateTime)
173
+ expect(v.to_time.to_i).to eql(t.to_time.to_i)
174
+ expect(v.year).to eql(t.year)
175
+ end
176
+
177
+ it "converts Time to DateTime" do
178
+ t = Time.now.utc
179
+ v = Box.new(birth: t).birth
180
+ expect(v.class).to eql(DateTime)
181
+ expect(v.to_time.to_i).to eql(t.to_i)
182
+ expect(v.year).to eql(t.year)
183
+ end
184
+
152
185
  it "converts unix timestamps to DateTime" do
153
186
  v = Box.new(birth: 1234567890).birth
154
187
  expect(v.class).to eql(DateTime)
@@ -214,6 +247,25 @@ describe Frenchy::Model do
214
247
  expect(v.id).to eql(1)
215
248
  end
216
249
 
250
+ it "supports subclass items" do
251
+ v = Box.new(subclass: {id: 1}).subclass
252
+ expect(v).to be_an_instance_of(Box::SubclassItem)
253
+ expect(v.id).to eql(1)
254
+ end
255
+
256
+ it "supports subtype items with type keyword" do
257
+ v = Box.new(subtype: {id: 2}).subtype
258
+ expect(v).to be_an_instance_of(Box::SubtypeItem)
259
+ expect(v.id).to eql(2)
260
+ end
261
+
262
+ it "supports embedded items with embed keyword" do
263
+ v = Box.new(child: {id: 3, name: "Jane"}).child
264
+ expect(v).to be_an_instance_of(Box::Child)
265
+ expect(v.id).to eql(3)
266
+ expect(v.name).to eql("Jane")
267
+ end
268
+
217
269
  it "establishes many model relationships" do
218
270
  v = Box.new(items: [{id: 1}, {id: 2}]).items
219
271
  expect(v).to be_an_instance_of(Frenchy::Collection)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frenchy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Coene
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-24 00:00:00.000000000 Z
11
+ date: 2016-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json