obfusk-data 0.0.2.SNAPSHOT.20130211214657 → 0.0.2.SNAPSHOT.20130212031255
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/README.md +26 -4
- data/Rakefile +7 -2
- data/lib/obfusk/data/base.rb +49 -0
- data/lib/obfusk/data/hamster.rb +65 -0
- data/lib/obfusk/data/hash.rb +70 -0
- data/lib/obfusk/data/version.rb +1 -1
- data/spec/_data.rb +94 -0
- data/spec/obfusk/data/hamster_spec.rb +84 -0
- data/spec/obfusk/data/hash_spec.rb +70 -0
- data/spec/obfusk/data_spec.rb +58 -134
- metadata +13 -7
data/README.md
CHANGED
@@ -51,6 +51,32 @@ Obfusk::Data.valid? tree,
|
|
51
51
|
# => true
|
52
52
|
```
|
53
53
|
|
54
|
+
```ruby
|
55
|
+
class X < Obfusk::Data::ValidHash
|
56
|
+
data do
|
57
|
+
field :spam, []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Y < Obfusk::Data::ValidHamster
|
62
|
+
data do
|
63
|
+
field :spam, []
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
x = X.new spam: 99; x[:spam] = 88
|
68
|
+
# OK
|
69
|
+
|
70
|
+
X.new
|
71
|
+
# raises Obfusk::Data::ValidHash::InvalidError
|
72
|
+
|
73
|
+
y = Y.new spam: 'yuck!'
|
74
|
+
# OK
|
75
|
+
|
76
|
+
Y.put :invalid, 'oops.'
|
77
|
+
# raises Obfusk::Data::ValidHamster::InvalidError
|
78
|
+
```
|
79
|
+
|
54
80
|
[]: }}}1
|
55
81
|
|
56
82
|
## Specs & Docs
|
@@ -64,10 +90,6 @@ Obfusk::Data.valid? tree,
|
|
64
90
|
## TODO
|
65
91
|
[]: {{{1
|
66
92
|
|
67
|
-
* add more ruby-ish api ?
|
68
|
-
|
69
|
-
#
|
70
|
-
|
71
93
|
* write more specs
|
72
94
|
* write more docs
|
73
95
|
* show isa errors
|
data/Rakefile
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
desc 'Run specs'
|
2
2
|
task :spec do
|
3
|
+
sh 'rspec -c'
|
4
|
+
end
|
5
|
+
|
6
|
+
desc 'Run specs verbosely'
|
7
|
+
task 'spec:verbose' do
|
3
8
|
sh 'rspec -cfd'
|
4
9
|
end
|
5
10
|
|
@@ -9,7 +14,7 @@ task :docs do
|
|
9
14
|
end
|
10
15
|
|
11
16
|
desc 'List undocumented objects'
|
12
|
-
task :
|
17
|
+
task 'docs:undoc' do
|
13
18
|
sh 'yard stats --list-undoc'
|
14
19
|
end
|
15
20
|
|
@@ -27,6 +32,6 @@ task :snapshot do
|
|
27
32
|
end
|
28
33
|
|
29
34
|
desc 'Undo SNAPSHOT gem'
|
30
|
-
task 'snapshot
|
35
|
+
task 'snapshot:undo' do
|
31
36
|
sh 'git checkout -- lib/obfusk/data/version.rb'
|
32
37
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data/base.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 'obfusk/data'
|
13
|
+
|
14
|
+
module Obfusk
|
15
|
+
module Data
|
16
|
+
|
17
|
+
module Base
|
18
|
+
|
19
|
+
def self.included (base)
|
20
|
+
base.extend ClassMethods
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def data (*a, &b)
|
26
|
+
const_set :VALIDATOR, Obfusk::Data.data(*a, &b)
|
27
|
+
end
|
28
|
+
|
29
|
+
def union (*a, &b)
|
30
|
+
const_set :VALIDATOR, Obfusk::Data.union(*a, &b)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate!
|
36
|
+
e = Obfusk::Data.validate self.class::VALIDATOR, self
|
37
|
+
raise self.class::InvalidError, e.join('; ') if e
|
38
|
+
end
|
39
|
+
|
40
|
+
def valid?
|
41
|
+
Obfusk::Data.valid? self.class::VALIDATOR, self
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data/hamster.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 'obfusk/data/base'
|
13
|
+
|
14
|
+
module Obfusk
|
15
|
+
module Data
|
16
|
+
|
17
|
+
# @todo document
|
18
|
+
# @note
|
19
|
+
# getting this to work depends on Hamster implementation details
|
20
|
+
# as well as some black magic ;-(
|
21
|
+
class ValidHamster < Hamster::Hash # {{{1
|
22
|
+
|
23
|
+
include Base
|
24
|
+
|
25
|
+
class InvalidError < RuntimeError; end
|
26
|
+
|
27
|
+
def self.__from_hamster (x)
|
28
|
+
data = x.instance_eval { [@trie, @default] }
|
29
|
+
y = allocate
|
30
|
+
y.instance_eval { @trie, @default = data }
|
31
|
+
y
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.__to_hamster (x)
|
35
|
+
data = x.instance_eval { [@trie, @default] }
|
36
|
+
y = Hamster::Hash.allocate
|
37
|
+
y.instance_eval { @trie, @default = data }
|
38
|
+
y
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.new (*a, &b)
|
42
|
+
x = __from_hamster Hamster::Hash.new(*a, &b)
|
43
|
+
x.validate!; x
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.empty
|
47
|
+
x = @empty ||= new; x.validate!; x
|
48
|
+
end
|
49
|
+
|
50
|
+
def except (*a, &b)
|
51
|
+
y = self.class.__to_hamster self
|
52
|
+
x = self.class.__from_hamster y.except(*a, &b)
|
53
|
+
x.validate!; x
|
54
|
+
end
|
55
|
+
|
56
|
+
def transform (*a, &b)
|
57
|
+
x = super; x.validate!; x
|
58
|
+
end
|
59
|
+
|
60
|
+
end # }}}1
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data/hash.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 'obfusk/data/base'
|
13
|
+
|
14
|
+
module Obfusk
|
15
|
+
module Data
|
16
|
+
|
17
|
+
# @todo document
|
18
|
+
class ValidHash < Hash # {{{1
|
19
|
+
|
20
|
+
include Base
|
21
|
+
|
22
|
+
class InvalidError < RuntimeError; end
|
23
|
+
|
24
|
+
%w{
|
25
|
+
[]= clear delete delete_if keep_if merge! reject! replace
|
26
|
+
select! shift store update
|
27
|
+
}.map(&:to_sym).each do |m|
|
28
|
+
define_method m do |*a, &b|
|
29
|
+
r = super(*a, &b); validate!; r
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.[] (*a, &b)
|
34
|
+
x = super; x.validate!; x
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize (data = {}, &block)
|
38
|
+
super(&block); self.merge! data
|
39
|
+
end
|
40
|
+
|
41
|
+
def compare_by_identity
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
45
|
+
def invert
|
46
|
+
Hash[self].invert
|
47
|
+
end
|
48
|
+
|
49
|
+
def merge (*a, &b)
|
50
|
+
x = super; x.validate!; x
|
51
|
+
end
|
52
|
+
|
53
|
+
def reject (*a, &b)
|
54
|
+
x = super; x.validate!; x
|
55
|
+
end
|
56
|
+
|
57
|
+
def select (*a, &b)
|
58
|
+
x = self.class[super]; x.validate!; x # TODO
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_hash
|
62
|
+
Hash[self]
|
63
|
+
end
|
64
|
+
|
65
|
+
end # }}}1
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
data/lib/obfusk/data/version.rb
CHANGED
data/spec/_data.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : _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 'obfusk/data'
|
13
|
+
|
14
|
+
module Obfusk::Data__Spec
|
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
|
+
end
|
93
|
+
|
94
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data/hamster_spec.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 'obfusk/data/hamster'
|
13
|
+
|
14
|
+
module Obfusk::Data::Hamster__Spec
|
15
|
+
|
16
|
+
class Bar < Obfusk::Data::ValidHamster
|
17
|
+
data other_fields: ->(x) { /other/.match x } do
|
18
|
+
field :bar, [->(x) { /bar/.match x }], optional: true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Baz < Obfusk::Data::ValidHamster
|
23
|
+
data do
|
24
|
+
field :baz , []
|
25
|
+
field :maybe, [], optional: true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
E = Obfusk::Data::ValidHamster::InvalidError
|
30
|
+
|
31
|
+
# --
|
32
|
+
|
33
|
+
describe Obfusk::Data::ValidHamster do
|
34
|
+
|
35
|
+
context 'Bar' do # {{{1
|
36
|
+
it 'valid empty Bar (2x)' do
|
37
|
+
Bar.new; Bar.empty
|
38
|
+
end
|
39
|
+
it 'valid Bar' do
|
40
|
+
Bar.new bar: 'bar?!'
|
41
|
+
end
|
42
|
+
it 'valid Bar w/ other field' do
|
43
|
+
Bar.new some_other_field: 37
|
44
|
+
end
|
45
|
+
it 'invalid Bar' do
|
46
|
+
expect { Bar.new baz: 42 }.to raise_error E
|
47
|
+
end
|
48
|
+
it 'invalid Bar merge' do
|
49
|
+
b = Bar.new
|
50
|
+
expect { b.merge Hamster.hash baz: 42 }.to raise_error E
|
51
|
+
end
|
52
|
+
it 'invalid Bar put' do
|
53
|
+
b = Bar.new
|
54
|
+
expect { b.put :bar, 'hi!' }.to raise_error E
|
55
|
+
end
|
56
|
+
end # }}}1
|
57
|
+
|
58
|
+
context 'Baz' do # {{{1
|
59
|
+
it 'valid Baz' do
|
60
|
+
Baz.new baz: 'ok!'
|
61
|
+
end
|
62
|
+
it 'valid Baz except' do
|
63
|
+
b = Baz.new baz: 1, maybe: 2
|
64
|
+
b.except :maybe
|
65
|
+
end
|
66
|
+
it 'invalid empty Baz (new)' do
|
67
|
+
expect { Baz.new }.to raise_error E
|
68
|
+
end
|
69
|
+
it 'invalid empty Baz (empty)' do
|
70
|
+
expect { Baz.empty }.to raise_error E
|
71
|
+
end
|
72
|
+
it 'invalid Baz except' do
|
73
|
+
b = Baz.new baz: 1, maybe: 2
|
74
|
+
expect { b.except :baz }.to raise_error E
|
75
|
+
end
|
76
|
+
end # }}}1
|
77
|
+
|
78
|
+
# ... TODO ...
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/data/hash_spec.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 'obfusk/data/hash'
|
13
|
+
|
14
|
+
module Obfusk::Data::Hash__Spec
|
15
|
+
|
16
|
+
class Bar < Obfusk::Data::ValidHash
|
17
|
+
data other_fields: ->(x) { /other/.match x } do
|
18
|
+
field :bar, [->(x) { /bar/.match x }], optional: true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Baz < Obfusk::Data::ValidHash
|
23
|
+
data do
|
24
|
+
field :baz, []
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
E = Obfusk::Data::ValidHash::InvalidError
|
29
|
+
|
30
|
+
# --
|
31
|
+
|
32
|
+
describe Obfusk::Data::ValidHash do
|
33
|
+
|
34
|
+
context 'Bar' do # {{{1
|
35
|
+
it 'valid empty Bar' do
|
36
|
+
Bar.new
|
37
|
+
end
|
38
|
+
it 'valid Bar' do
|
39
|
+
Bar.new bar: 'bar?!'
|
40
|
+
end
|
41
|
+
it 'valid Bar w/ other field' do
|
42
|
+
Bar.new some_other_field: 37
|
43
|
+
end
|
44
|
+
it 'invalid Bar' do
|
45
|
+
expect { Bar.new baz: 42 }.to raise_error E
|
46
|
+
end
|
47
|
+
it 'invalid Bar merge' do
|
48
|
+
b = Bar.new
|
49
|
+
expect { b.merge baz: 42 }.to raise_error E
|
50
|
+
end
|
51
|
+
it 'invalid Bar []=' do
|
52
|
+
b = Bar.new
|
53
|
+
expect { b[:bar] = 'hi!' }.to raise_error E
|
54
|
+
end
|
55
|
+
end # }}}1
|
56
|
+
|
57
|
+
context 'Baz' do # {{{1
|
58
|
+
it 'invalid Baz clear' do
|
59
|
+
b = Baz.new baz: 'ok'
|
60
|
+
expect { b.clear }.to raise_error E
|
61
|
+
end
|
62
|
+
end # }}}1
|
63
|
+
|
64
|
+
# ... TODO ...
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
data/spec/obfusk/data_spec.rb
CHANGED
@@ -1,148 +1,72 @@
|
|
1
1
|
# -- ; {{{1
|
2
2
|
#
|
3
|
-
# File : obfusk/
|
3
|
+
# File : obfusk/data_spec.rb
|
4
4
|
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
-
# Date : 2013-02-
|
5
|
+
# Date : 2013-02-11
|
6
6
|
#
|
7
7
|
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
8
|
# Licence : GPLv2 or EPLv1
|
9
9
|
#
|
10
10
|
# -- ; }}}1
|
11
11
|
|
12
|
-
require '
|
12
|
+
require './spec/_data'
|
13
|
+
|
14
|
+
module Obfusk::Data__Spec
|
15
|
+
|
16
|
+
describe Obfusk::Data do
|
17
|
+
|
18
|
+
context 'Foo' do # {{{1
|
19
|
+
it 'valid empty Foo' do
|
20
|
+
should be_valid Foo, {}
|
21
|
+
end
|
22
|
+
it 'valid Foo' do
|
23
|
+
should be_valid Foo, { data_bar: 37 }
|
24
|
+
end
|
25
|
+
it 'invalid Foo' do
|
26
|
+
should_not be_valid Foo, { baz: 42 }
|
27
|
+
end
|
28
|
+
end # }}}1
|
29
|
+
|
30
|
+
context 'Tree' do # {{{1
|
31
|
+
it 'valid empty Tree' do
|
32
|
+
should be_valid Tree, { type: :empty }
|
33
|
+
end
|
34
|
+
it 'invalid empty Tree' do
|
35
|
+
should_not be_valid Tree, { type: :empty, Foo: 'hi!' }
|
36
|
+
end
|
37
|
+
it 'valid Tree leaf' do
|
38
|
+
should be_valid Tree, { type: :leaf, value: 3.14 }
|
39
|
+
end
|
40
|
+
it 'invalid Tree leaf' do
|
41
|
+
should_not be_valid Tree, { type: :leaf }
|
42
|
+
end
|
43
|
+
it 'valid Tree node' do
|
44
|
+
should be_valid Tree,
|
45
|
+
{ type: :node,
|
46
|
+
left: { type: :empty },
|
47
|
+
right: { type: :leaf, value: 'spam!' } }
|
48
|
+
end
|
49
|
+
it 'invalid Tree node' do
|
50
|
+
should_not be_valid Tree,
|
51
|
+
{ type: :node, left: { type: :empty }, right: nil }
|
52
|
+
end
|
53
|
+
end # }}}1
|
54
|
+
|
55
|
+
context 'Address' do # {{{1
|
56
|
+
it 'valid Address' do
|
57
|
+
should be_valid Address,
|
58
|
+
{ street: 'baker street', number: '221b',
|
59
|
+
town: 'london', postal_code: '???', country: 'uk' }
|
60
|
+
end
|
61
|
+
it 'invalid Address' do
|
62
|
+
should_not be_valid Address,
|
63
|
+
{ street: 'baker street', number: 404 }
|
64
|
+
end
|
65
|
+
end # }}}1
|
66
|
+
|
67
|
+
# ... TODO ...
|
13
68
|
|
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
69
|
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
70
|
|
147
71
|
end
|
148
72
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: obfusk-data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.2.SNAPSHOT.
|
4
|
+
version: 0.0.2.SNAPSHOT.20130212031255
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2013-02-11 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hamster
|
16
|
-
requirement: &
|
16
|
+
requirement: &20985220 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *20985220
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &20928520 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *20928520
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &20927780 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *20927780
|
47
47
|
description: ! '...
|
48
48
|
|
49
49
|
'
|
@@ -56,8 +56,14 @@ files:
|
|
56
56
|
- .yardopts
|
57
57
|
- README.md
|
58
58
|
- Rakefile
|
59
|
+
- lib/obfusk/data/hamster.rb
|
59
60
|
- lib/obfusk/data/version.rb
|
61
|
+
- lib/obfusk/data/hash.rb
|
62
|
+
- lib/obfusk/data/base.rb
|
60
63
|
- lib/obfusk/data.rb
|
64
|
+
- spec/_data.rb
|
65
|
+
- spec/obfusk/data/hash_spec.rb
|
66
|
+
- spec/obfusk/data/hamster_spec.rb
|
61
67
|
- spec/obfusk/data_spec.rb
|
62
68
|
- obfusk-data.gemspec
|
63
69
|
homepage: https://github.com/obfusk/rb-obfusk-data
|