data_bindings 0.0.1 → 0.0.2
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/.gitignore +1 -0
- data/Gemfile +0 -1
- data/data_bindings.gemspec +2 -2
- data/lib/data_bindings.rb +1 -2
- data/lib/data_bindings/adapters/params.rb +4 -8
- data/lib/data_bindings/generator.rb +14 -4
- data/lib/data_bindings/version.rb +1 -1
- data/lib/ext/hashie.rb +110 -0
- data/test/class_test.rb +25 -0
- metadata +23 -36
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/data_bindings.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "data_bindings/version"
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "data_bindings"
|
7
7
|
s.version = DataBindings::VERSION
|
8
|
-
s.authors = ["Joshual Hull"]
|
8
|
+
s.authors = ["Joshual Hull", "Benjamin Coe"]
|
9
9
|
s.email = ["joshbuddy@gmail.com"]
|
10
10
|
s.homepage = "http://github.com/joshbuddy/data_bindings"
|
11
11
|
s.summary = %q{Bind data to and from things}
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_runtime_dependency 'hashie', '= 2.0.0.beta'
|
21
|
+
# s.add_runtime_dependency 'hashie', '= 2.0.0.beta' NOTE: re-add after this is really published
|
22
22
|
|
23
23
|
# specify any dependencies here; for example:
|
24
24
|
s.add_development_dependency 'bson'
|
data/lib/data_bindings.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'hashie'
|
1
|
+
require 'ext/hashie'
|
2
2
|
|
3
3
|
require 'data_bindings/util'
|
4
4
|
require 'data_bindings/generator'
|
@@ -24,7 +24,6 @@ module DataBindings
|
|
24
24
|
class << self
|
25
25
|
# Sends all methods calls to DefaultGenerator
|
26
26
|
def method_missing(m, *args, &blk)
|
27
|
-
DefaultGeneratorInstance.send(:build!)
|
28
27
|
DefaultGeneratorInstance.send(m, *args, &blk)
|
29
28
|
end
|
30
29
|
|
@@ -11,14 +11,10 @@ module DataBindings
|
|
11
11
|
|
12
12
|
|
13
13
|
def parse_nested_query(qs, d = nil)
|
14
|
-
|
15
|
-
|
16
|
-
(qs || '').split(d ? /[#{d}] */n : /[&;] */n).each do |p|
|
14
|
+
(qs || '').split(d ? /[#{d}] */n : /[&;] */n).inject({}) do |params, p|
|
17
15
|
k, v = p.split('=', 2).map { |s| CGI::unescape(s) }
|
18
16
|
normalize_params(params, k, v)
|
19
17
|
end
|
20
|
-
|
21
|
-
return params
|
22
18
|
end
|
23
19
|
|
24
20
|
private
|
@@ -26,9 +22,9 @@ module DataBindings
|
|
26
22
|
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
27
23
|
k = $1 || ''
|
28
24
|
after = $' || ''
|
29
|
-
|
30
|
-
return if k.empty?
|
31
|
-
|
25
|
+
|
26
|
+
return params if k.empty?
|
27
|
+
|
32
28
|
if after == ""
|
33
29
|
params[k] = v
|
34
30
|
elsif after == "[]"
|
@@ -44,7 +44,7 @@ module DataBindings
|
|
44
44
|
# @yield [*Object] All arguments passed to the method used to invoke this reader
|
45
45
|
def reader(name, &blk)
|
46
46
|
@reader_module.define_singleton_method(name, &blk)
|
47
|
-
|
47
|
+
build!
|
48
48
|
end
|
49
49
|
|
50
50
|
# Defines a writer
|
@@ -73,7 +73,7 @@ module DataBindings
|
|
73
73
|
# @param [Object] The adapter
|
74
74
|
def register(name, cls)
|
75
75
|
@adapters[name] = cls
|
76
|
-
|
76
|
+
build!
|
77
77
|
end
|
78
78
|
|
79
79
|
# Resets the generator to a blank state
|
@@ -97,10 +97,21 @@ module DataBindings
|
|
97
97
|
@native_constructors ||= {}
|
98
98
|
end
|
99
99
|
|
100
|
+
def class_for(name, superclass = Object, &blk)
|
101
|
+
cls = Class.new(superclass, &blk)
|
102
|
+
for_native(name) { |props|
|
103
|
+
inst = cls.allocate
|
104
|
+
props.each do |k, v|
|
105
|
+
inst.instance_variable_set(:"@#{k}", v)
|
106
|
+
end
|
107
|
+
inst.send(:initialize)
|
108
|
+
inst
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
100
112
|
private
|
101
113
|
# @api private
|
102
114
|
def build!
|
103
|
-
return if @built
|
104
115
|
@adapters.each do |name, cls|
|
105
116
|
unless @adapter_classes[name]
|
106
117
|
@adapter_classes[name] = cls.to_s.split('::').inject(Object) {|const, n| const.const_get(n)}
|
@@ -118,7 +129,6 @@ module DataBindings
|
|
118
129
|
end
|
119
130
|
end
|
120
131
|
end
|
121
|
-
@build = true
|
122
132
|
end
|
123
133
|
end
|
124
134
|
|
data/lib/ext/hashie.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
module Hashie
|
2
|
+
module Extensions
|
3
|
+
# IndifferentAccess gives you the ability to not care
|
4
|
+
# whether your hash has string or symbol keys. Made famous
|
5
|
+
# in Rails for accessing query and POST parameters, this
|
6
|
+
# is a handy tool for making sure your hash has maximum
|
7
|
+
# utility.
|
8
|
+
#
|
9
|
+
# One unique feature of this mixin is that it will recursively
|
10
|
+
# inject itself into sub-hash instances without modifying
|
11
|
+
# the actual class of the sub-hash.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# class MyHash < Hash
|
15
|
+
# include Hashie::Extensions::MergeInitializer
|
16
|
+
# include Hashie::Extensions::IndifferentAccess
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# h = MyHash.new(:foo => 'bar', 'baz' => 'blip')
|
20
|
+
# h['foo'] # => 'bar'
|
21
|
+
# h[:foo] # => 'bar'
|
22
|
+
# h[:baz] # => 'blip'
|
23
|
+
# h['baz'] # => 'blip'
|
24
|
+
#
|
25
|
+
module IndifferentAccess
|
26
|
+
def self.included(base)
|
27
|
+
base.class_eval do
|
28
|
+
alias_method :regular_writer, :[]=
|
29
|
+
alias_method :[]=, :indifferent_writer
|
30
|
+
%w(default update fetch delete key? values_at).each do |m|
|
31
|
+
alias_method "regular_#{m}", m
|
32
|
+
alias_method m, "indifferent_#{m}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# This will inject indifferent access into an instance of
|
38
|
+
# a hash without modifying the actual class. This is what
|
39
|
+
# allows IndifferentAccess to spread to sub-hashes.
|
40
|
+
def self.inject!(hash)
|
41
|
+
(class << hash; self; end).send :include, Hashie::Extensions::IndifferentAccess
|
42
|
+
hash.convert!
|
43
|
+
end
|
44
|
+
|
45
|
+
# Injects indifferent access into a duplicate of the hash
|
46
|
+
# provided. See #inject!
|
47
|
+
def self.inject(hash)
|
48
|
+
inject!(hash.dup)
|
49
|
+
end
|
50
|
+
|
51
|
+
def convert_key(key)
|
52
|
+
key.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
# Iterates through the keys and values, reconverting them to
|
56
|
+
# their proper indifferent state. Used when IndifferentAccess
|
57
|
+
# is injecting itself into member hashes.
|
58
|
+
def convert!
|
59
|
+
keys.each do |k|
|
60
|
+
regular_writer convert_key(k), convert_value(self.regular_delete(k))
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
def convert_value(value)
|
66
|
+
if hash_lacking_indifference?(value)
|
67
|
+
Hashie::Extensions::IndifferentAccess.inject(value.dup)
|
68
|
+
elsif value.is_a?(::Array)
|
69
|
+
value.dup.replace(value.map { |e| convert_value(e) })
|
70
|
+
else
|
71
|
+
value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def indifferent_default(key = nil)
|
76
|
+
return self[convert_key(key)] if key?(key)
|
77
|
+
regular_default(key)
|
78
|
+
end
|
79
|
+
|
80
|
+
def indifferent_update(other_hash)
|
81
|
+
return regular_update(other_hash) if hash_with_indifference?(other_hash)
|
82
|
+
other_hash.each_pair do |k,v|
|
83
|
+
self[k] = v
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def indifferent_writer(key, value); regular_writer convert_key(key), convert_value(value) end
|
88
|
+
def indifferent_fetch(key, *args); regular_fetch convert_key(key), *args end
|
89
|
+
def indifferent_delete(key); regular_delete convert_key(key) end
|
90
|
+
def indifferent_key?(key); regular_key? convert_key(key) end
|
91
|
+
def indifferent_values_at(*indices); indices.map{|i| self[i] } end
|
92
|
+
|
93
|
+
def indifferent_access?; true end
|
94
|
+
|
95
|
+
protected
|
96
|
+
|
97
|
+
def hash_lacking_indifference?(other)
|
98
|
+
other.is_a?(::Hash) &&
|
99
|
+
!(other.respond_to?(:indifferent_access?) &&
|
100
|
+
other.indifferent_access?)
|
101
|
+
end
|
102
|
+
|
103
|
+
def hash_with_indifference?(other)
|
104
|
+
other.is_a?(::Hash) &&
|
105
|
+
other.respond_to?(:indifferent_access?) &&
|
106
|
+
other.indifferent_access?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/test/class_test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
describe "Data Bindings classes" do
|
4
|
+
before do
|
5
|
+
@generator = DataBindings::DefaultGenerator.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "class generation" do
|
9
|
+
it "should create a basic class" do
|
10
|
+
@generator.type(:person) do
|
11
|
+
property :name
|
12
|
+
property :favorite_food
|
13
|
+
end
|
14
|
+
@generator.class_for(:person) do
|
15
|
+
def to_s
|
16
|
+
"#{@name} likes to eat #{@favorite_food}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
josh = @generator.from_ruby('name' => 'josh', 'favorite_food' => 'lasagna').bind(:person).to_native
|
21
|
+
assert_equal "josh likes to eat lasagna", josh.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
metadata
CHANGED
@@ -1,41 +1,39 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_bindings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joshual Hull
|
14
|
+
- Benjamin Coe
|
14
15
|
autorequire:
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2012-02-
|
19
|
+
date: 2012-02-02 00:00:00 Z
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
22
|
+
name: bson
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
25
|
none: false
|
25
26
|
requirements:
|
26
|
-
- - "
|
27
|
+
- - ">="
|
27
28
|
- !ruby/object:Gem::Version
|
28
|
-
hash:
|
29
|
+
hash: 3
|
29
30
|
segments:
|
30
|
-
- 2
|
31
31
|
- 0
|
32
|
-
|
33
|
-
|
34
|
-
version: 2.0.0.beta
|
35
|
-
type: :runtime
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
36
34
|
version_requirements: *id001
|
37
35
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
36
|
+
name: multi_json
|
39
37
|
prerelease: false
|
40
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
@@ -49,7 +47,7 @@ dependencies:
|
|
49
47
|
type: :development
|
50
48
|
version_requirements: *id002
|
51
49
|
- !ruby/object:Gem::Dependency
|
52
|
-
name:
|
50
|
+
name: nokogiri
|
53
51
|
prerelease: false
|
54
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
53
|
none: false
|
@@ -63,7 +61,7 @@ dependencies:
|
|
63
61
|
type: :development
|
64
62
|
version_requirements: *id003
|
65
63
|
- !ruby/object:Gem::Dependency
|
66
|
-
name:
|
64
|
+
name: builder
|
67
65
|
prerelease: false
|
68
66
|
requirement: &id004 !ruby/object:Gem::Requirement
|
69
67
|
none: false
|
@@ -77,7 +75,7 @@ dependencies:
|
|
77
75
|
type: :development
|
78
76
|
version_requirements: *id004
|
79
77
|
- !ruby/object:Gem::Dependency
|
80
|
-
name:
|
78
|
+
name: httparty
|
81
79
|
prerelease: false
|
82
80
|
requirement: &id005 !ruby/object:Gem::Requirement
|
83
81
|
none: false
|
@@ -91,7 +89,7 @@ dependencies:
|
|
91
89
|
type: :development
|
92
90
|
version_requirements: *id005
|
93
91
|
- !ruby/object:Gem::Dependency
|
94
|
-
name:
|
92
|
+
name: minitest
|
95
93
|
prerelease: false
|
96
94
|
requirement: &id006 !ruby/object:Gem::Requirement
|
97
95
|
none: false
|
@@ -105,7 +103,7 @@ dependencies:
|
|
105
103
|
type: :development
|
106
104
|
version_requirements: *id006
|
107
105
|
- !ruby/object:Gem::Dependency
|
108
|
-
name:
|
106
|
+
name: rake
|
109
107
|
prerelease: false
|
110
108
|
requirement: &id007 !ruby/object:Gem::Requirement
|
111
109
|
none: false
|
@@ -119,7 +117,7 @@ dependencies:
|
|
119
117
|
type: :development
|
120
118
|
version_requirements: *id007
|
121
119
|
- !ruby/object:Gem::Dependency
|
122
|
-
name:
|
120
|
+
name: fakeweb
|
123
121
|
prerelease: false
|
124
122
|
requirement: &id008 !ruby/object:Gem::Requirement
|
125
123
|
none: false
|
@@ -133,7 +131,7 @@ dependencies:
|
|
133
131
|
type: :development
|
134
132
|
version_requirements: *id008
|
135
133
|
- !ruby/object:Gem::Dependency
|
136
|
-
name:
|
134
|
+
name: yard
|
137
135
|
prerelease: false
|
138
136
|
requirement: &id009 !ruby/object:Gem::Requirement
|
139
137
|
none: false
|
@@ -147,7 +145,7 @@ dependencies:
|
|
147
145
|
type: :development
|
148
146
|
version_requirements: *id009
|
149
147
|
- !ruby/object:Gem::Dependency
|
150
|
-
name:
|
148
|
+
name: redcarpet
|
151
149
|
prerelease: false
|
152
150
|
requirement: &id010 !ruby/object:Gem::Requirement
|
153
151
|
none: false
|
@@ -161,7 +159,7 @@ dependencies:
|
|
161
159
|
type: :development
|
162
160
|
version_requirements: *id010
|
163
161
|
- !ruby/object:Gem::Dependency
|
164
|
-
name:
|
162
|
+
name: tnetstring
|
165
163
|
prerelease: false
|
166
164
|
requirement: &id011 !ruby/object:Gem::Requirement
|
167
165
|
none: false
|
@@ -174,20 +172,6 @@ dependencies:
|
|
174
172
|
version: "0"
|
175
173
|
type: :development
|
176
174
|
version_requirements: *id011
|
177
|
-
- !ruby/object:Gem::Dependency
|
178
|
-
name: tnetstring
|
179
|
-
prerelease: false
|
180
|
-
requirement: &id012 !ruby/object:Gem::Requirement
|
181
|
-
none: false
|
182
|
-
requirements:
|
183
|
-
- - ">="
|
184
|
-
- !ruby/object:Gem::Version
|
185
|
-
hash: 3
|
186
|
-
segments:
|
187
|
-
- 0
|
188
|
-
version: "0"
|
189
|
-
type: :development
|
190
|
-
version_requirements: *id012
|
191
175
|
description: Bind data to and from things.
|
192
176
|
email:
|
193
177
|
- joshbuddy@gmail.com
|
@@ -219,8 +203,10 @@ files:
|
|
219
203
|
- lib/data_bindings/unbound.rb
|
220
204
|
- lib/data_bindings/util.rb
|
221
205
|
- lib/data_bindings/version.rb
|
206
|
+
- lib/ext/hashie.rb
|
222
207
|
- test/array_test.rb
|
223
208
|
- test/bson_test.rb
|
209
|
+
- test/class_test.rb
|
224
210
|
- test/converter_test.rb
|
225
211
|
- test/data_bindings_test.rb
|
226
212
|
- test/fixtures/1.json
|
@@ -268,6 +254,7 @@ summary: Bind data to and from things
|
|
268
254
|
test_files:
|
269
255
|
- test/array_test.rb
|
270
256
|
- test/bson_test.rb
|
257
|
+
- test/class_test.rb
|
271
258
|
- test/converter_test.rb
|
272
259
|
- test/data_bindings_test.rb
|
273
260
|
- test/fixtures/1.json
|