obfusk-data 0.0.2.SNAPSHOT.20130211214657
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/.yardopts +1 -0
- data/README.md +96 -0
- data/Rakefile +32 -0
- data/lib/obfusk/data/version.rb +6 -0
- data/lib/obfusk/data.rb +221 -0
- data/obfusk-data.gemspec +29 -0
- data/spec/obfusk/data_spec.rb +149 -0
- metadata +90 -0
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
[]: {{{1
|
2
|
+
|
3
|
+
File : README.md
|
4
|
+
Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
Date : 2013-02-11
|
6
|
+
|
7
|
+
Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
Version : 0.0.2.SNAPSHOT
|
9
|
+
|
10
|
+
[]: }}}1
|
11
|
+
|
12
|
+
## Description
|
13
|
+
[]: {{{1
|
14
|
+
|
15
|
+
[rb-]obfusk-data - data validation combinator library for ruby
|
16
|
+
|
17
|
+
...
|
18
|
+
|
19
|
+
https://github.com/obfusk/clj-obfusk-data in ruby.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
isa = ->(cls, obj) { cls === obj } .curry
|
23
|
+
is_string = isa[String]
|
24
|
+
is_email = ->(x) { %r{^.*@.*\.[a-z]+$}.match x }
|
25
|
+
|
26
|
+
address = Obfusk::Data.data do
|
27
|
+
field [:street, :number, :postal_code, :town], [is_string]
|
28
|
+
field :country, [is_string], optional: true
|
29
|
+
end
|
30
|
+
|
31
|
+
person = Obfusk::Data.data do
|
32
|
+
field [:first_name, :last_name, :phone_number], [is_string]
|
33
|
+
field :email, [is_string, is_email]
|
34
|
+
field :address, [], isa: [address]
|
35
|
+
end
|
36
|
+
|
37
|
+
tree = Obfusk::Data.union :type do |_tree|
|
38
|
+
data :empty
|
39
|
+
data :leaf do
|
40
|
+
field :value, []
|
41
|
+
end
|
42
|
+
data :node do
|
43
|
+
field [:left, :right], [], isa: [_tree]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Obfusk::Data.valid? tree,
|
48
|
+
{ type: :node,
|
49
|
+
left: { type: :empty },
|
50
|
+
right: { type: :leaf, value: "spam!" } }
|
51
|
+
# => true
|
52
|
+
```
|
53
|
+
|
54
|
+
[]: }}}1
|
55
|
+
|
56
|
+
## Specs & Docs
|
57
|
+
[]: {{{1
|
58
|
+
|
59
|
+
$ rake spec
|
60
|
+
$ rake docs
|
61
|
+
|
62
|
+
[]: }}}1
|
63
|
+
|
64
|
+
## TODO
|
65
|
+
[]: {{{1
|
66
|
+
|
67
|
+
* add more ruby-ish api ?
|
68
|
+
|
69
|
+
#
|
70
|
+
|
71
|
+
* write more specs
|
72
|
+
* write more docs
|
73
|
+
* show isa errors
|
74
|
+
* ...
|
75
|
+
|
76
|
+
[]: }}}1
|
77
|
+
|
78
|
+
## License
|
79
|
+
[]: {{{1
|
80
|
+
|
81
|
+
GPLv2 [1] or EPLv1 [2].
|
82
|
+
|
83
|
+
[]: }}}1
|
84
|
+
|
85
|
+
## References
|
86
|
+
[]: {{{1
|
87
|
+
|
88
|
+
[1] GNU General Public License, version 2
|
89
|
+
--- http://www.opensource.org/licenses/GPL-2.0
|
90
|
+
|
91
|
+
[2] Eclipse Public License, version 1
|
92
|
+
--- http://www.opensource.org/licenses/EPL-1.0
|
93
|
+
|
94
|
+
[]: }}}1
|
95
|
+
|
96
|
+
[]: ! ( vim: set tw=70 sw=2 sts=2 et fdm=marker : )
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
desc 'Run specs'
|
2
|
+
task :spec do
|
3
|
+
sh 'rspec -cfd'
|
4
|
+
end
|
5
|
+
|
6
|
+
desc 'Generate docs'
|
7
|
+
task :docs do
|
8
|
+
sh 'yardoc | cat'
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'List undocumented objects'
|
12
|
+
task :undocumented do
|
13
|
+
sh 'yard stats --list-undoc'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Cleanup'
|
17
|
+
task :clean do
|
18
|
+
sh 'rm -rf .yardoc/ doc/ *.gem'
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Build SNAPSHOT gem'
|
22
|
+
task :snapshot do
|
23
|
+
v = Time.new.strftime '%Y%m%d%H%M%S'
|
24
|
+
f = 'lib/obfusk/data/version.rb'
|
25
|
+
sh "sed -ri~ 's!(SNAPSHOT)!\\1.#{v}!' #{f}"
|
26
|
+
sh 'gem build obfusk-data.gemspec'
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Undo SNAPSHOT gem'
|
30
|
+
task 'snapshot-undo' do
|
31
|
+
sh 'git checkout -- lib/obfusk/data/version.rb'
|
32
|
+
end
|
data/lib/obfusk/data.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-02-11
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2 or EPLv1
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'hamster'
|
13
|
+
require 'set'
|
14
|
+
|
15
|
+
module Obfusk
|
16
|
+
module Data
|
17
|
+
|
18
|
+
# this proxy allows us to define recursive types
|
19
|
+
PROXY = ->(; f, bind, proxy) { # {{{1
|
20
|
+
proxy = ->(*args) {
|
21
|
+
raise 'unbound PROXY called!' unless f # TODO
|
22
|
+
f[*args]
|
23
|
+
}
|
24
|
+
bind = ->(g) {
|
25
|
+
raise 'PROXY can only be bound once' if f # TODO
|
26
|
+
f = g
|
27
|
+
}
|
28
|
+
[proxy, bind]
|
29
|
+
} # }}}1
|
30
|
+
|
31
|
+
# this helper allows us to run field in the block passed to data
|
32
|
+
class FieldsHelper # {{{1
|
33
|
+
# init
|
34
|
+
def initialize
|
35
|
+
@_fields = []
|
36
|
+
end
|
37
|
+
|
38
|
+
# add field
|
39
|
+
def field (*args)
|
40
|
+
@_fields << Obfusk::Data.field(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
# get fields
|
44
|
+
def _fields
|
45
|
+
@_fields
|
46
|
+
end
|
47
|
+
end # }}}1
|
48
|
+
|
49
|
+
# this helper allows us to run data in the block passed to union
|
50
|
+
class DatasHelper # {{{1
|
51
|
+
# init
|
52
|
+
def initialize
|
53
|
+
@_datas = {}
|
54
|
+
end
|
55
|
+
|
56
|
+
# add data
|
57
|
+
def data (value, &block)
|
58
|
+
@_datas[value] = Obfusk::Data._blk_flds block
|
59
|
+
end
|
60
|
+
|
61
|
+
# get datas
|
62
|
+
def _datas
|
63
|
+
@_datas
|
64
|
+
end
|
65
|
+
end # }}}1
|
66
|
+
|
67
|
+
# --
|
68
|
+
|
69
|
+
# empty sequence?
|
70
|
+
def self._blank? (x)
|
71
|
+
String === x || Enumerable === x ? x.empty? : false
|
72
|
+
end
|
73
|
+
|
74
|
+
# add error
|
75
|
+
def self._error (st, *msg)
|
76
|
+
e1 = st[:errors]
|
77
|
+
e2 = e1.add msg.join
|
78
|
+
st.put :errors, e2
|
79
|
+
end
|
80
|
+
|
81
|
+
# --
|
82
|
+
|
83
|
+
# if only we had clojure's :keys ;-(
|
84
|
+
def self._get_keys (x, keys)
|
85
|
+
x.values_at *keys.map(&:to_sym)
|
86
|
+
end
|
87
|
+
|
88
|
+
# run block in instance of helper
|
89
|
+
def self._blk_hlp (cls, block, *args)
|
90
|
+
x = cls.new
|
91
|
+
x.instance_exec *args, &block
|
92
|
+
x
|
93
|
+
end
|
94
|
+
|
95
|
+
# turn block into fields using FieldsHelper
|
96
|
+
def self._blk_flds (block, *args)
|
97
|
+
block ? _blk_hlp(FieldsHelper, block, *args)._fields : []
|
98
|
+
end
|
99
|
+
|
100
|
+
# --
|
101
|
+
|
102
|
+
# data validator w/o block magic
|
103
|
+
def self.data_ (fields, opts = {}) # {{{1
|
104
|
+
o_flds = opts[:other_fields]
|
105
|
+
isa = opts.fetch :isa, []
|
106
|
+
st = Hamster.hash errors: Hamster.vector,
|
107
|
+
processed: Hamster.set
|
108
|
+
|
109
|
+
->(x ; st_, ks, pks, eks) {
|
110
|
+
if isa.any? { |x| validate x }
|
111
|
+
_error st '[data] has failed isa' # TODO
|
112
|
+
else
|
113
|
+
st_ = fields.reduce(st) { |s, f| f[x, s] }
|
114
|
+
ks = x.keys.to_set
|
115
|
+
pks = st_[:processed]
|
116
|
+
eks = ks - pks
|
117
|
+
|
118
|
+
if !o_flds && !eks.empty?
|
119
|
+
_error st_, '[data] has extraneous fields'
|
120
|
+
elsif o_flds.respond_to?(:to_proc) && !eks.all?(&o_flds)
|
121
|
+
_error st_, '[data] has invalid other fields'
|
122
|
+
else
|
123
|
+
st_
|
124
|
+
end
|
125
|
+
end
|
126
|
+
}
|
127
|
+
end # }}}1
|
128
|
+
|
129
|
+
# A data validator. ...
|
130
|
+
def self.data (opts = {}, &block)
|
131
|
+
proxy, bind = PROXY[]
|
132
|
+
data = data_ _blk_flds(block, proxy), opts
|
133
|
+
bind[data]
|
134
|
+
data
|
135
|
+
end
|
136
|
+
|
137
|
+
# --
|
138
|
+
|
139
|
+
# validate a field
|
140
|
+
def self._validate_field (name, predicates, opts, x, st) # {{{1
|
141
|
+
field = x[name]
|
142
|
+
preds = predicates.map(&:to_proc)
|
143
|
+
isa = opts.fetch :isa, []
|
144
|
+
|
145
|
+
st_ = st.put :processed, st[:processed].add(name)
|
146
|
+
err = ->(*msg) { _error st_, (opts[:message] || msg.join) }
|
147
|
+
|
148
|
+
optional, o_nil, blank, o_if, o_if_not =
|
149
|
+
_get_keys opts, %w{ optional o_nil blank o_if o_if_not }
|
150
|
+
|
151
|
+
if (o_if && !o_if[x]) || (o_if_not && o_if_not[x])
|
152
|
+
st_
|
153
|
+
elsif !x.has_key? name
|
154
|
+
optional ? st_ : err['[field] not found: ', name]
|
155
|
+
elsif field.nil?
|
156
|
+
o_nil || optional ? st_ : err['[field] is nil: ', name]
|
157
|
+
elsif _blank?(field) && !(blank || optional)
|
158
|
+
err['[field] is blank: ', name]
|
159
|
+
elsif !preds.all? { |p| p[field] }
|
160
|
+
err['[field] has failed predicates: ', name]
|
161
|
+
elsif isa.any? { |x| validate x, field }
|
162
|
+
err['[field] has failed isa: ', name] # TODO
|
163
|
+
else
|
164
|
+
st_
|
165
|
+
end
|
166
|
+
end # }}}1
|
167
|
+
|
168
|
+
# A data field. Predicates are functions that are invoked with
|
169
|
+
# the field's value, and must all return true. ...
|
170
|
+
def self.field (names, predicates, opts = {})
|
171
|
+
f = ->(n, x, s) { _validate_field n, predicates, opts, x, s }
|
172
|
+
ns = Enumerable === names ? names : [names]
|
173
|
+
|
174
|
+
->(x, st) { ns.reduce(st) { |s, name| f[name, x, s] } }
|
175
|
+
end
|
176
|
+
|
177
|
+
# --
|
178
|
+
|
179
|
+
# union w/o block magic and data wrapping
|
180
|
+
def self.union__ (key, datas)
|
181
|
+
f = field key, [->(x) { Symbol === x }]
|
182
|
+
|
183
|
+
->(x, st ; fields) {
|
184
|
+
fields = datas.fetch(x.fetch(key)) + [f]
|
185
|
+
fields.reduce(st) { |s, field| field[x, s] }
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
# union w/o block magic
|
190
|
+
def self.union_ (key, datas, opts = {})
|
191
|
+
data_ [union__(key, datas)], opts
|
192
|
+
end
|
193
|
+
|
194
|
+
# Union of data fields. ...
|
195
|
+
def self.union (key, opts = {}, &block)
|
196
|
+
proxy, bind = PROXY[]
|
197
|
+
datas = _blk_hlp(DatasHelper, block, proxy)._datas
|
198
|
+
data = union_ key, datas, opts
|
199
|
+
bind[data]
|
200
|
+
data
|
201
|
+
end
|
202
|
+
|
203
|
+
# --
|
204
|
+
|
205
|
+
# Validate.
|
206
|
+
# @return [nil] if valid
|
207
|
+
# @return [<String>] errors otherwise
|
208
|
+
def self.validate (f, x)
|
209
|
+
e = f[x][:errors]
|
210
|
+
e.empty? ? nil : e.to_a
|
211
|
+
end
|
212
|
+
|
213
|
+
# Validate.
|
214
|
+
def self.valid? (f, x)
|
215
|
+
validate(f, x).nil?
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
data/obfusk-data.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../lib/obfusk/data/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'obfusk-data'
|
5
|
+
s.homepage = 'https://github.com/obfusk/rb-obfusk-data'
|
6
|
+
s.summary = 'data validation combinator library for ruby'
|
7
|
+
|
8
|
+
s.description = <<-END.gsub(/^ {4}/, '') # TODO
|
9
|
+
...
|
10
|
+
END
|
11
|
+
|
12
|
+
s.version = Obfusk::Data::VERSION
|
13
|
+
s.date = Obfusk::Data::DATE
|
14
|
+
|
15
|
+
s.authors = [ 'Felix C. Stegerman' ]
|
16
|
+
s.email = %w{ flx@obfusk.net }
|
17
|
+
|
18
|
+
s.licenses = %w{ GPLv2 EPLv1 }
|
19
|
+
|
20
|
+
s.files = %w{ .yardopts README.md Rakefile } \
|
21
|
+
+ Dir[*%w{ {lib,spec}/**/*.rb *.gemspec }]
|
22
|
+
|
23
|
+
s.add_runtime_dependency 'hamster'
|
24
|
+
|
25
|
+
s.add_development_dependency 'rake'
|
26
|
+
s.add_development_dependency 'rspec'
|
27
|
+
|
28
|
+
s.required_ruby_version = '>= 1.9.1'
|
29
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-02-08
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2 or EPLv1
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'obfusk/data'
|
13
|
+
|
14
|
+
# --
|
15
|
+
|
16
|
+
isa = ->(cls, obj) { cls === obj } .curry
|
17
|
+
is_string = isa[String]
|
18
|
+
|
19
|
+
is_email = ->(x) { %r{^.*@.*\.[a-z]+$}.match x }
|
20
|
+
is_url = ->(x) { %r{^https?://.*$}.match x }
|
21
|
+
|
22
|
+
is_object_id = ->(x) {
|
23
|
+
is_string[x] && x.length == 16 &&
|
24
|
+
x.chars.all? { |c| %{^[a-zA-Z0-9]$}.match c }
|
25
|
+
}
|
26
|
+
|
27
|
+
is_id_seq = ->(x) { isa[Enumberable, x] && x.all?(&is_object_id) }
|
28
|
+
is_id_map = ->(m) {
|
29
|
+
isa[Hash, m] && m.all? { |k,v| is_string[k] && is_object_id[v] }
|
30
|
+
}
|
31
|
+
|
32
|
+
# --
|
33
|
+
|
34
|
+
foo = Obfusk::Data.data other_fields: ->(x) { %r{^data_}.match x }
|
35
|
+
|
36
|
+
tree = Obfusk::Data.union :type do |_tree|
|
37
|
+
data :empty
|
38
|
+
data :leaf do
|
39
|
+
field :value, []
|
40
|
+
end
|
41
|
+
data :node do
|
42
|
+
field [:left, :right], [], isa: [_tree]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# --
|
47
|
+
|
48
|
+
address = Obfusk::Data.data do
|
49
|
+
field [:street, :number, :postal_code, :town], [is_string]
|
50
|
+
field :country, [is_string], optional: true
|
51
|
+
end
|
52
|
+
|
53
|
+
person = Obfusk::Data.data do
|
54
|
+
field [:first_name, :last_name, :phone_number], [is_string]
|
55
|
+
field :email, [is_string, is_email]
|
56
|
+
field :address, [], isa: [address]
|
57
|
+
end
|
58
|
+
|
59
|
+
# --
|
60
|
+
|
61
|
+
collection = Obfusk::Data.data do
|
62
|
+
field :_id , [is_object_id]
|
63
|
+
field :app , [is_string]
|
64
|
+
field :icon , [is_object_id]
|
65
|
+
field :items, [is_id_seq]
|
66
|
+
field :title, [is_string], optional: true
|
67
|
+
end
|
68
|
+
|
69
|
+
item = Obfusk::Data.data do
|
70
|
+
field :_id , [is_object_id]
|
71
|
+
field :type , [is_string]
|
72
|
+
field :icon , [is_object_id], nil: true
|
73
|
+
field :data , [] , optional: true
|
74
|
+
field :title , [is_string] , optional: true
|
75
|
+
field :url , [is_url] , optional: true
|
76
|
+
field [:refs, :files] , [is_id_map] , optional: true
|
77
|
+
|
78
|
+
# (not= (contains? x :url)
|
79
|
+
# (contains? (get x :files {}) :url)) ; TODO
|
80
|
+
end
|
81
|
+
|
82
|
+
item_files = Obfusk::Data.data do
|
83
|
+
field :url, [is_url], optional: true
|
84
|
+
end
|
85
|
+
|
86
|
+
image_item = Obfusk::Data.data isa: [item] do
|
87
|
+
field :icon , [:nil?]
|
88
|
+
field :data , [:nil?], optional: true
|
89
|
+
field :files, isa: [item_files]
|
90
|
+
end
|
91
|
+
|
92
|
+
# --
|
93
|
+
|
94
|
+
describe Obfusk::Data do
|
95
|
+
|
96
|
+
context 'foo' do # {{{1
|
97
|
+
it 'valid empty foo' do
|
98
|
+
should be_valid foo, {}
|
99
|
+
end
|
100
|
+
it 'valid foo' do
|
101
|
+
should be_valid foo, { data_bar: 37 }
|
102
|
+
end
|
103
|
+
it 'invalid foo' do
|
104
|
+
should_not be_valid foo, { baz: 42 }
|
105
|
+
end
|
106
|
+
end # }}}1
|
107
|
+
|
108
|
+
context 'tree' do # {{{1
|
109
|
+
it 'valid empty tree' do
|
110
|
+
should be_valid tree, { type: :empty }
|
111
|
+
end
|
112
|
+
it 'invalid empty tree' do
|
113
|
+
should_not be_valid tree, { type: :empty, foo: 'hi!' }
|
114
|
+
end
|
115
|
+
it 'valid tree leaf' do
|
116
|
+
should be_valid tree, { type: :leaf, value: 3.14 }
|
117
|
+
end
|
118
|
+
it 'invalid tree leaf' do
|
119
|
+
should_not be_valid tree, { type: :leaf }
|
120
|
+
end
|
121
|
+
it 'valid tree node' do
|
122
|
+
should be_valid tree,
|
123
|
+
{ type: :node,
|
124
|
+
left: { type: :empty },
|
125
|
+
right: { type: :leaf, value: 'spam!' } }
|
126
|
+
end
|
127
|
+
it 'invalid tree node' do
|
128
|
+
should_not be_valid tree,
|
129
|
+
{ type: :node, left: { type: :empty }, right: nil }
|
130
|
+
end
|
131
|
+
end # }}}1
|
132
|
+
|
133
|
+
context 'address' do # {{{1
|
134
|
+
it 'valid address' do
|
135
|
+
should be_valid address,
|
136
|
+
{ street: 'baker street', number: '221b',
|
137
|
+
town: 'london', postal_code: '???', country: 'uk' }
|
138
|
+
end
|
139
|
+
it 'invalid address' do
|
140
|
+
should_not be_valid address,
|
141
|
+
{ street: 'baker street', number: 404 }
|
142
|
+
end
|
143
|
+
end # }}}1
|
144
|
+
|
145
|
+
# ... TODO ...
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: obfusk-data
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2.SNAPSHOT.20130211214657
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Felix C. Stegerman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: hamster
|
16
|
+
requirement: &9955760 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *9955760
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &9955240 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *9955240
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &9954660 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *9954660
|
47
|
+
description: ! '...
|
48
|
+
|
49
|
+
'
|
50
|
+
email:
|
51
|
+
- flx@obfusk.net
|
52
|
+
executables: []
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- .yardopts
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- lib/obfusk/data/version.rb
|
60
|
+
- lib/obfusk/data.rb
|
61
|
+
- spec/obfusk/data_spec.rb
|
62
|
+
- obfusk-data.gemspec
|
63
|
+
homepage: https://github.com/obfusk/rb-obfusk-data
|
64
|
+
licenses:
|
65
|
+
- GPLv2
|
66
|
+
- EPLv1
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.9.1
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>'
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.1
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.11
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: data validation combinator library for ruby
|
89
|
+
test_files: []
|
90
|
+
has_rdoc:
|