frenchy 0.4.0 → 0.5.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 +4 -4
- data/lib/frenchy.rb +1 -0
- data/lib/frenchy/enum.rb +71 -0
- data/lib/frenchy/model.rb +23 -0
- data/lib/frenchy/version.rb +1 -1
- data/spec/lib/frenchy/enum_spec.rb +114 -0
- data/spec/lib/frenchy/model_spec.rb +31 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c053d86535fc11bfb4789c95b7a3207089b81a3e
|
|
4
|
+
data.tar.gz: 99f313562478d7607816b095e176fef88d2fdeed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8da2c669175476f793dad871f7e737e1b65b89a4c98dca7582e0d23b3f9f63633ad56c2e343cacef2452acc6d53755d6e8bd7d505f4a0d813722747494253f5f
|
|
7
|
+
data.tar.gz: 77ef9f74818af9c594d721f270ac1fcde31433e43204a636a979426f4a9ea7f7995e0fea7601ccda015df669fc642b74f37f0995f2bf3ef13b6f668bbd3d64a9
|
data/lib/frenchy.rb
CHANGED
data/lib/frenchy/enum.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module Frenchy
|
|
2
|
+
module Enum
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.extend(ClassMethods)
|
|
5
|
+
|
|
6
|
+
base.class_eval do
|
|
7
|
+
@enums = {}
|
|
8
|
+
@default = nil
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_accessor :name, :tag
|
|
13
|
+
|
|
14
|
+
def initialize(attrs={})
|
|
15
|
+
attrs.each do |k, v|
|
|
16
|
+
send("#{k}=", v) if respond_to?("#{k}=")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def inspect
|
|
21
|
+
"\#<#{self.class.name}::#{name}=#{tag}>"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_i
|
|
25
|
+
tag
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_str
|
|
29
|
+
to_s
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_sym
|
|
33
|
+
name
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def to_s
|
|
37
|
+
name.to_s.underscore
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def ==(other)
|
|
41
|
+
(other.is_a?(Symbol) && (name == other)) ||
|
|
42
|
+
(other.respond_to?(:to_i) && (other.to_i == tag)) ||
|
|
43
|
+
(other.respond_to?(:to_s) && (other.to_s == to_s || other.to_s == name.to_s)) ||
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module ClassMethods
|
|
48
|
+
def define(name, tag, options={})
|
|
49
|
+
name = name.to_sym
|
|
50
|
+
tag = tag.to_i
|
|
51
|
+
options.stringify_keys!
|
|
52
|
+
|
|
53
|
+
enum = new(name: name, tag: tag)
|
|
54
|
+
const_set(name, enum)
|
|
55
|
+
@enums[tag] = enum
|
|
56
|
+
|
|
57
|
+
if options["default"]
|
|
58
|
+
@default = tag
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def default
|
|
63
|
+
@enums[@default]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def find(tag)
|
|
67
|
+
@enums[tag.to_i] || default
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/lib/frenchy/model.rb
CHANGED
|
@@ -77,6 +77,15 @@ module Frenchy
|
|
|
77
77
|
klass.class_eval(&block)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
# Macro to add an enum type
|
|
81
|
+
def enum(name, &block)
|
|
82
|
+
klass = Class.new(self) do
|
|
83
|
+
include Frenchy::Enum
|
|
84
|
+
end
|
|
85
|
+
const_set(name.to_s.camelize, klass)
|
|
86
|
+
klass.class_eval(&block)
|
|
87
|
+
end
|
|
88
|
+
|
|
80
89
|
# Macro to create a subtype and associated field
|
|
81
90
|
def embed(name, options={}, &block)
|
|
82
91
|
type(name, &block)
|
|
@@ -88,6 +97,11 @@ module Frenchy
|
|
|
88
97
|
name = name.to_s
|
|
89
98
|
options.stringify_keys!
|
|
90
99
|
|
|
100
|
+
if options["enum"]
|
|
101
|
+
options["type"] = "enum"
|
|
102
|
+
options["class_name"] ||= options["enum"].to_s.camelize
|
|
103
|
+
end
|
|
104
|
+
|
|
91
105
|
type = (options["type"] || "string").to_s
|
|
92
106
|
aliases = (options["aliases"] || [])
|
|
93
107
|
|
|
@@ -160,6 +174,15 @@ module Frenchy
|
|
|
160
174
|
set(name, Hash[v])
|
|
161
175
|
end
|
|
162
176
|
|
|
177
|
+
when "enum"
|
|
178
|
+
# Resolve the class name
|
|
179
|
+
klass = const_get(options["class_name"])
|
|
180
|
+
|
|
181
|
+
# Convert value to enum class
|
|
182
|
+
define_method("#{name}=") do |v|
|
|
183
|
+
set(name, klass.find(v.to_i))
|
|
184
|
+
end
|
|
185
|
+
|
|
163
186
|
else
|
|
164
187
|
# Unknown types have their type constantized and initialized with the value. This
|
|
165
188
|
# allows us to support things like other Frenchy::Model classes, ActiveRecord models, etc.
|
data/lib/frenchy/version.rb
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
class SimpleEnum
|
|
4
|
+
include Frenchy::Enum
|
|
5
|
+
|
|
6
|
+
define :NONE, 0
|
|
7
|
+
define :PARTIAL, 1
|
|
8
|
+
define :FULL, 2
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class EnumWithDefault
|
|
12
|
+
include Frenchy::Enum
|
|
13
|
+
|
|
14
|
+
define :NONE, 0
|
|
15
|
+
define :PARTIAL_SUPPORT, 1
|
|
16
|
+
define :FULL_SUPPORT, 2, default: true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe Frenchy::Enum do
|
|
20
|
+
describe ".default" do
|
|
21
|
+
it "returns the default if set" do
|
|
22
|
+
e = EnumWithDefault.default
|
|
23
|
+
expect(e).to eql(EnumWithDefault::FULL_SUPPORT)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "returns nil if not set" do
|
|
27
|
+
e = SimpleEnum.default
|
|
28
|
+
expect(e).to eql nil
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe ".find" do
|
|
33
|
+
it "finds by tag" do
|
|
34
|
+
e = SimpleEnum.find(1)
|
|
35
|
+
expect(e).to be_an_instance_of(SimpleEnum)
|
|
36
|
+
expect(e.tag).to eql(1)
|
|
37
|
+
expect(e.name).to eql(:PARTIAL)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "returns nil when no match is found" do
|
|
41
|
+
e = SimpleEnum.find(5)
|
|
42
|
+
expect(e).to eql(nil)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "returns default when no match is found and a default is declared" do
|
|
46
|
+
e = EnumWithDefault.find(5)
|
|
47
|
+
expect(e).to be_an_instance_of(EnumWithDefault)
|
|
48
|
+
expect(e.tag).to eql(2)
|
|
49
|
+
expect(e.name).to eql(:FULL_SUPPORT)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "constants" do
|
|
54
|
+
it "declares constants" do
|
|
55
|
+
e = SimpleEnum::PARTIAL
|
|
56
|
+
expect(e).to be_an_instance_of(SimpleEnum)
|
|
57
|
+
expect(e.tag).to eql(1)
|
|
58
|
+
expect(e.name).to eql(:PARTIAL)
|
|
59
|
+
|
|
60
|
+
e = SimpleEnum::FULL
|
|
61
|
+
expect(e).to be_an_instance_of(SimpleEnum)
|
|
62
|
+
expect(e.tag).to eql(2)
|
|
63
|
+
expect(e.name).to eql(:FULL)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "model" do
|
|
68
|
+
it "describes itself" do
|
|
69
|
+
e = SimpleEnum::FULL
|
|
70
|
+
expect(e.inspect).to eql "\#<SimpleEnum::FULL=2>"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "== compares equality" do
|
|
74
|
+
e = SimpleEnum::FULL
|
|
75
|
+
e2 = EnumWithDefault::FULL_SUPPORT
|
|
76
|
+
f = SimpleEnum::PARTIAL
|
|
77
|
+
|
|
78
|
+
# Separate reference
|
|
79
|
+
expect(e == SimpleEnum::FULL).to eql(true)
|
|
80
|
+
|
|
81
|
+
# Comparison by enum
|
|
82
|
+
expect(e == e).to eql(true)
|
|
83
|
+
|
|
84
|
+
# Comparison across enum types
|
|
85
|
+
expect(e == e2).to eql(true)
|
|
86
|
+
expect(e == f).to eql(false)
|
|
87
|
+
|
|
88
|
+
# Comparison by tag
|
|
89
|
+
expect(e == 2).to eql(true)
|
|
90
|
+
expect(2 == e).to eql(true)
|
|
91
|
+
|
|
92
|
+
# Comparison by string
|
|
93
|
+
expect(e == "full").to eql(true)
|
|
94
|
+
expect("full" == e).to eql(true)
|
|
95
|
+
expect(e == "FULL").to eql(true)
|
|
96
|
+
expect("FULL" == e).to eql(true)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "#to_i returns the tag" do
|
|
100
|
+
e = SimpleEnum::FULL
|
|
101
|
+
expect(e.to_i).to eql(2)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "#to_s returns a lowercase name" do
|
|
105
|
+
e = SimpleEnum::FULL
|
|
106
|
+
expect(e.to_s).to eql("full")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "#to_s returns underscore names" do
|
|
110
|
+
e = EnumWithDefault::FULL_SUPPORT
|
|
111
|
+
expect(e.to_s).to eql("full_support")
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -23,6 +23,12 @@ end
|
|
|
23
23
|
class Box
|
|
24
24
|
include Frenchy::Model
|
|
25
25
|
|
|
26
|
+
enum :priority do
|
|
27
|
+
define :NORMAL, 0, default: true
|
|
28
|
+
define :PRIORITY, 1
|
|
29
|
+
define :EXPRESS, 2
|
|
30
|
+
end
|
|
31
|
+
|
|
26
32
|
class SubclassItem
|
|
27
33
|
include Frenchy::Model
|
|
28
34
|
|
|
@@ -53,6 +59,9 @@ class Box
|
|
|
53
59
|
field :special, type: "special_item", class_name: "SuperSpecialItem"
|
|
54
60
|
field :subclass, type: "subclass_item"
|
|
55
61
|
field :subtype, type: "subtype_item"
|
|
62
|
+
|
|
63
|
+
field :priority, enum: "priority"
|
|
64
|
+
field :other_priority, enum: "priority", default: Priority::NORMAL
|
|
56
65
|
end
|
|
57
66
|
|
|
58
67
|
class SimpleModelDecorator
|
|
@@ -234,6 +243,28 @@ describe Frenchy::Model do
|
|
|
234
243
|
end
|
|
235
244
|
end
|
|
236
245
|
|
|
246
|
+
describe "enum" do
|
|
247
|
+
it "defaults to the default" do
|
|
248
|
+
v = Box.new
|
|
249
|
+
expect(v.priority).to eql(nil)
|
|
250
|
+
expect(v.other_priority).to eql(Box::Priority::NORMAL)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "accepts fixnums" do
|
|
254
|
+
v = Box.new(priority: 2)
|
|
255
|
+
expect(v.priority).to eql(Box::Priority::EXPRESS)
|
|
256
|
+
expect(v.priority.to_i).to eql(2)
|
|
257
|
+
expect(v.priority.to_s).to eql("express")
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "accepts enums" do
|
|
261
|
+
v = Box.new(priority: Box::Priority::PRIORITY)
|
|
262
|
+
expect(v.priority).to eql(Box::Priority::PRIORITY)
|
|
263
|
+
expect(v.priority.to_i).to eql(1)
|
|
264
|
+
expect(v.priority.to_s).to eql("priority")
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
237
268
|
describe "model relationships" do
|
|
238
269
|
it "establishes single model relationships" do
|
|
239
270
|
v = Box.new(item: {id: 1}).item
|
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.
|
|
4
|
+
version: 0.5.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: 2016-04-
|
|
11
|
+
date: 2016-04-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -142,6 +142,7 @@ files:
|
|
|
142
142
|
- lib/frenchy/client.rb
|
|
143
143
|
- lib/frenchy/collection.rb
|
|
144
144
|
- lib/frenchy/core_ext.rb
|
|
145
|
+
- lib/frenchy/enum.rb
|
|
145
146
|
- lib/frenchy/error.rb
|
|
146
147
|
- lib/frenchy/instrumentation.rb
|
|
147
148
|
- lib/frenchy/model.rb
|
|
@@ -152,6 +153,7 @@ files:
|
|
|
152
153
|
- spec/lib/frenchy/client_spec.rb
|
|
153
154
|
- spec/lib/frenchy/collection_spec.rb
|
|
154
155
|
- spec/lib/frenchy/core_ext_spec.rb
|
|
156
|
+
- spec/lib/frenchy/enum_spec.rb
|
|
155
157
|
- spec/lib/frenchy/error_spec.rb
|
|
156
158
|
- spec/lib/frenchy/model_spec.rb
|
|
157
159
|
- spec/lib/frenchy/request_spec.rb
|
|
@@ -187,6 +189,7 @@ test_files:
|
|
|
187
189
|
- spec/lib/frenchy/client_spec.rb
|
|
188
190
|
- spec/lib/frenchy/collection_spec.rb
|
|
189
191
|
- spec/lib/frenchy/core_ext_spec.rb
|
|
192
|
+
- spec/lib/frenchy/enum_spec.rb
|
|
190
193
|
- spec/lib/frenchy/error_spec.rb
|
|
191
194
|
- spec/lib/frenchy/model_spec.rb
|
|
192
195
|
- spec/lib/frenchy/request_spec.rb
|