frenchy 0.3.0 → 0.4.0

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.
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