nrser 0.0.25 → 0.0.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -11
- data/lib/nrser.rb +5 -1
- data/lib/nrser/array.rb +10 -53
- data/lib/nrser/enumerable.rb +21 -0
- data/lib/nrser/hash.rb +13 -476
- data/lib/nrser/hash/bury.rb +154 -0
- data/lib/nrser/hash/deep_merge.rb +57 -0
- data/lib/nrser/hash/except_keys.rb +42 -0
- data/lib/nrser/hash/guess_label_key_type.rb +37 -0
- data/lib/nrser/hash/slice_keys.rb +41 -0
- data/lib/nrser/hash/stringify_keys.rb +37 -0
- data/lib/nrser/hash/symbolize_keys.rb +41 -0
- data/lib/nrser/hash/transform_keys.rb +45 -0
- data/lib/nrser/merge_by.rb +26 -0
- data/lib/nrser/message.rb +125 -0
- data/lib/nrser/meta/props.rb +2 -2
- data/lib/nrser/meta/props/prop.rb +5 -2
- data/lib/nrser/object.rb +5 -0
- data/lib/nrser/object/as_array.rb +37 -0
- data/lib/nrser/object/as_hash.rb +101 -0
- data/lib/nrser/{truthy.rb → object/truthy.rb} +0 -0
- data/lib/nrser/proc.rb +132 -0
- data/lib/nrser/refinements.rb +1 -2
- data/lib/nrser/refinements/array.rb +94 -5
- data/lib/nrser/refinements/enumerable.rb +5 -0
- data/lib/nrser/refinements/hash.rb +43 -6
- data/lib/nrser/refinements/object.rb +22 -2
- data/lib/nrser/refinements/symbol.rb +12 -0
- data/lib/nrser/refinements/tree.rb +41 -0
- data/lib/nrser/rspex.rb +329 -0
- data/lib/nrser/string.rb +3 -0
- data/lib/nrser/string/looks_like.rb +51 -0
- data/lib/nrser/temp/where.rb +52 -0
- data/lib/nrser/tree.rb +86 -0
- data/lib/nrser/tree/leaves.rb +92 -0
- data/lib/nrser/tree/map_leaves.rb +63 -0
- data/lib/nrser/tree/transform.rb +30 -0
- data/lib/nrser/types.rb +9 -4
- data/lib/nrser/types/any.rb +1 -1
- data/lib/nrser/types/array.rb +167 -25
- data/lib/nrser/types/{hash.rb → hashes.rb} +19 -5
- data/lib/nrser/types/in.rb +47 -0
- data/lib/nrser/types/is_a.rb +2 -2
- data/lib/nrser/types/labels.rb +49 -0
- data/lib/nrser/types/numbers.rb +63 -27
- data/lib/nrser/types/pairs.rb +109 -0
- data/lib/nrser/types/responds.rb +2 -3
- data/lib/nrser/types/strings.rb +17 -18
- data/lib/nrser/types/symbols.rb +39 -0
- data/lib/nrser/types/trees.rb +93 -0
- data/lib/nrser/types/tuples.rb +116 -0
- data/lib/nrser/types/type.rb +26 -2
- data/lib/nrser/version.rb +1 -1
- data/spec/nrser/hash/{guess_name_type_spec.rb → guess_label_key_type_spec.rb} +3 -3
- data/spec/nrser/hash_spec.rb +0 -20
- data/spec/nrser/merge_by_spec.rb +73 -0
- data/spec/nrser/meta/props_spec.rb +136 -43
- data/spec/nrser/op/message_spec.rb +62 -0
- data/spec/nrser/refinements/array_spec.rb +36 -0
- data/spec/nrser/refinements/hash_spec.rb +34 -0
- data/spec/nrser/string/looks_like_spec.rb +31 -0
- data/spec/nrser/tree/each_branch_spec.rb +82 -0
- data/spec/nrser/tree/leaves_spec.rb +112 -0
- data/spec/nrser/tree/transform_spec.rb +165 -0
- data/spec/nrser/types/array_spec.rb +82 -0
- data/spec/nrser/types/attrs_spec.rb +4 -4
- data/spec/nrser/types/pairs_spec.rb +41 -0
- data/spec/nrser/types/paths_spec.rb +3 -3
- data/spec/nrser/types/strings_spec.rb +66 -0
- data/spec/nrser/types/symbols_spec.rb +38 -0
- data/spec/nrser/types/tuples_spec.rb +37 -0
- data/spec/nrser/types_spec.rb +0 -13
- data/spec/spec_helper.rb +71 -22
- metadata +58 -10
- data/lib/nrser/spex.rb +0 -68
- data/lib/nrser/types/symbol.rb +0 -23
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
|
10
|
+
# NRSER::Types.array
|
11
|
+
# ========================================================================
|
12
|
+
#
|
13
|
+
describe "NRSER::Types.array" do
|
14
|
+
subject { t.method :array }
|
15
|
+
|
16
|
+
it_behaves_like 'type maker method'
|
17
|
+
|
18
|
+
include_examples 'make type',
|
19
|
+
accepts: [
|
20
|
+
[],
|
21
|
+
[1, 2, 3],
|
22
|
+
[:a, 2, 'c']
|
23
|
+
],
|
24
|
+
|
25
|
+
rejects: [
|
26
|
+
nil,
|
27
|
+
{},
|
28
|
+
'1,2,3',
|
29
|
+
],
|
30
|
+
|
31
|
+
from_s: {
|
32
|
+
accepts: {
|
33
|
+
# String splitting with default splitter
|
34
|
+
'1,2,3' => ['1', '2', '3'],
|
35
|
+
'1, 2, 3' => ['1', '2', '3'],
|
36
|
+
"1,\n2,\n3" => ['1', '2', '3'],
|
37
|
+
|
38
|
+
# JSON encoded
|
39
|
+
JSON.dump([1, 2, 3]) => [1, 2, 3],
|
40
|
+
|
41
|
+
JSON.pretty_generate([
|
42
|
+
{x: 'ex!'},
|
43
|
+
{y: 'why?'}
|
44
|
+
]) => [{'x' => 'ex!'}, {'y' => 'why?'}],
|
45
|
+
},
|
46
|
+
},
|
47
|
+
|
48
|
+
and_is_expected: {
|
49
|
+
to: {
|
50
|
+
have_attributes: {
|
51
|
+
class: t::ArrayType,
|
52
|
+
name: 'ArrayType',
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
include_examples 'make type',
|
58
|
+
args: [t.int],
|
59
|
+
|
60
|
+
accepts: [
|
61
|
+
[],
|
62
|
+
[1, 2, -3, 0],
|
63
|
+
],
|
64
|
+
|
65
|
+
rejects: [
|
66
|
+
[1, 2, :c],
|
67
|
+
],
|
68
|
+
|
69
|
+
from_s: {
|
70
|
+
accepts: {
|
71
|
+
'1, 2, 3' => [1, 2, 3],
|
72
|
+
},
|
73
|
+
|
74
|
+
rejects: {
|
75
|
+
'a, b, c' => ArgumentError,
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
end # NRSER::Types.array
|
80
|
+
|
81
|
+
# ************************************************************************
|
82
|
+
|
@@ -10,13 +10,13 @@ describe "NRSER::Types.length" do
|
|
10
10
|
}
|
11
11
|
|
12
12
|
# Three ways to cut it:
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
include_examples 'make type', args: [ length: 0 ], **kwds
|
14
|
+
include_examples 'make type', args: [ 0 ], **kwds
|
15
|
+
include_examples 'make type', args: [ min: 0, max: 0], **kwds
|
16
16
|
|
17
17
|
end # zero length
|
18
18
|
|
19
|
-
|
19
|
+
include_examples 'make type',
|
20
20
|
args: [ {min: 3, max: 5}, name: '3to5Type' ],
|
21
21
|
|
22
22
|
accepts: [
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
|
10
|
+
# NRSER::Types.hash_pair
|
11
|
+
# ========================================================================
|
12
|
+
#
|
13
|
+
describe "NRSER::Types.hash_pair" do
|
14
|
+
subject { NRSER::Types.method :hash_pair }
|
15
|
+
|
16
|
+
it_behaves_like 'type maker method'
|
17
|
+
|
18
|
+
include_examples 'make type',
|
19
|
+
accepts: [
|
20
|
+
{x: 1},
|
21
|
+
],
|
22
|
+
|
23
|
+
rejects: [
|
24
|
+
{x: 1, y: 2},
|
25
|
+
]
|
26
|
+
|
27
|
+
include_examples 'make type',
|
28
|
+
args: [key: t.label, value: t.int],
|
29
|
+
|
30
|
+
accepts: [
|
31
|
+
{x: 1},
|
32
|
+
],
|
33
|
+
|
34
|
+
rejects: [
|
35
|
+
{x: :y},
|
36
|
+
]
|
37
|
+
|
38
|
+
end # NRSER::Types.hash_pair
|
39
|
+
|
40
|
+
# ************************************************************************
|
41
|
+
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe "NRSER::Types.dir_path" do
|
4
4
|
subject { NRSER::Types.method :dir_path }
|
5
5
|
|
6
|
-
|
6
|
+
include_examples 'make type',
|
7
7
|
accepts: [
|
8
8
|
'.',
|
9
9
|
'/',
|
@@ -23,7 +23,7 @@ end # NRSER::Types.dir_path
|
|
23
23
|
describe "NRSER::Types.file_path" do
|
24
24
|
subject { NRSER::Types.method :file_path }
|
25
25
|
|
26
|
-
|
26
|
+
include_examples 'make type',
|
27
27
|
accepts: [
|
28
28
|
( NRSER::ROOT / 'README.md' ),
|
29
29
|
],
|
@@ -43,7 +43,7 @@ describe "NRSER::Types.file_path" do
|
|
43
43
|
}
|
44
44
|
|
45
45
|
context "custom name" do
|
46
|
-
|
46
|
+
include_examples 'make type',
|
47
47
|
args: [ name: 'CustomType' ],
|
48
48
|
|
49
49
|
accepts: [
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
|
10
|
+
# NRSER::Types.str
|
11
|
+
# ========================================================================
|
12
|
+
#
|
13
|
+
describe "NRSER::Types.str" do
|
14
|
+
subject { NRSER::Types.method :str }
|
15
|
+
|
16
|
+
it_behaves_like 'type maker method'
|
17
|
+
|
18
|
+
include_examples 'make type',
|
19
|
+
accepts: [ 'hey', '' ],
|
20
|
+
rejects: [ 1, {}, nil, ],
|
21
|
+
from_s: {
|
22
|
+
accepts: {
|
23
|
+
'hey' => 'hey',
|
24
|
+
'' => '',
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
include_examples 'make type',
|
29
|
+
args: [length: 0],
|
30
|
+
accepts: [ '', ],
|
31
|
+
rejects: [ 'hey', ]
|
32
|
+
|
33
|
+
include_examples 'make type',
|
34
|
+
args: [length: 3],
|
35
|
+
accepts: [ 'hey', 'hoe' ],
|
36
|
+
rejects: [ 'he', 'ha' ]
|
37
|
+
|
38
|
+
end # NRSER::Types.str
|
39
|
+
|
40
|
+
# ************************************************************************
|
41
|
+
|
42
|
+
|
43
|
+
# NRSER::Types.non_empty_str
|
44
|
+
# ========================================================================
|
45
|
+
#
|
46
|
+
describe "NRSER::Types.non_empty_str" do
|
47
|
+
subject { NRSER::Types.method :non_empty_str }
|
48
|
+
|
49
|
+
it_behaves_like 'type maker method'
|
50
|
+
|
51
|
+
include_examples 'make type',
|
52
|
+
args: [],
|
53
|
+
accepts: [ 'hey', 'ho', "let's go" ],
|
54
|
+
rejects: [ '', nil, 1 ],
|
55
|
+
from_s: {
|
56
|
+
accepts: {
|
57
|
+
|
58
|
+
},
|
59
|
+
rejects: {
|
60
|
+
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
end # NRSER::Types.non_empty_str
|
65
|
+
|
66
|
+
# ************************************************************************
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
|
10
|
+
# NRSER::Types.non_empty_sym
|
11
|
+
# ========================================================================
|
12
|
+
#
|
13
|
+
describe "NRSER::Types.non_empty_sym" do
|
14
|
+
subject { NRSER::Types.method :non_empty_sym }
|
15
|
+
|
16
|
+
it_behaves_like 'type maker method'
|
17
|
+
|
18
|
+
include_examples 'make type',
|
19
|
+
args: [],
|
20
|
+
accepts: [ :x, :y ],
|
21
|
+
rejects: [ :'', nil, 'x', 1 ],
|
22
|
+
from_s: {
|
23
|
+
accepts: {
|
24
|
+
|
25
|
+
},
|
26
|
+
rejects: {
|
27
|
+
|
28
|
+
}
|
29
|
+
},
|
30
|
+
and_is_expected: {
|
31
|
+
to: {
|
32
|
+
have_attributes: {
|
33
|
+
name: 'NonEmptySym'
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
end # NRSER::Types.non_empty_sym
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
|
10
|
+
# NRSER::Types.tuple
|
11
|
+
# ========================================================================
|
12
|
+
#
|
13
|
+
describe "NRSER::Types.tuple" do
|
14
|
+
subject { NRSER::Types.method :tuple }
|
15
|
+
|
16
|
+
it_behaves_like 'type maker method'
|
17
|
+
|
18
|
+
include_examples 'make type',
|
19
|
+
args: [],
|
20
|
+
accepts: [ [] ],
|
21
|
+
rejects: [ [1] ]
|
22
|
+
|
23
|
+
include_examples 'make type',
|
24
|
+
args: [t.int, t.int],
|
25
|
+
accepts: [ [1, 2] ],
|
26
|
+
rejects: [ [1, :x], [1], [1, 2, 3] ],
|
27
|
+
from_s: {
|
28
|
+
accepts: {
|
29
|
+
'1, 2' => [1, 2],
|
30
|
+
'[1, 2]' => [1, 2],
|
31
|
+
},
|
32
|
+
rejects: {},
|
33
|
+
}
|
34
|
+
|
35
|
+
end # NRSER::Types.tuple
|
36
|
+
|
37
|
+
# ************************************************************************
|
data/spec/nrser/types_spec.rb
CHANGED
@@ -87,14 +87,6 @@ describe NRSER::Types do
|
|
87
87
|
},
|
88
88
|
},
|
89
89
|
|
90
|
-
t.str => {
|
91
|
-
pass: ['hey', ''],
|
92
|
-
fail: [1, {}, nil],
|
93
|
-
from_s: {
|
94
|
-
pass: ['hey', ''],
|
95
|
-
}
|
96
|
-
},
|
97
|
-
|
98
90
|
t.attrs(to_s: t.str) => {
|
99
91
|
pass: [''],
|
100
92
|
},
|
@@ -112,11 +104,6 @@ describe NRSER::Types do
|
|
112
104
|
fail: ['hey'],
|
113
105
|
},
|
114
106
|
|
115
|
-
t.str(length: 0) => {
|
116
|
-
pass: [''],
|
117
|
-
fail: ['hey'],
|
118
|
-
},
|
119
|
-
|
120
107
|
t.array => {
|
121
108
|
pass: [[], [1, 2, 3]],
|
122
109
|
fail: [nil, {}, '1,2,3'],
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
4
4
|
|
5
5
|
require 'nrser'
|
6
6
|
require 'nrser/logger'
|
7
|
-
require 'nrser/
|
7
|
+
require 'nrser/rspex'
|
8
8
|
|
9
9
|
MAIN = self
|
10
10
|
|
@@ -28,16 +28,29 @@ def expect_to_not_log &block
|
|
28
28
|
end
|
29
29
|
|
30
30
|
|
31
|
-
shared_examples "
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
shared_examples "type maker method" do |param_1|
|
32
|
+
context "provided `name:` option" do
|
33
|
+
let( :name ) { 'CustomTypeName' }
|
34
|
+
subject { super().call name: name }
|
35
|
+
|
36
|
+
it { is_expected.to be_a NRSER::Types::Type }
|
37
|
+
it { is_expected.to have_attributes name: name }
|
38
|
+
end # provided `name:` option
|
39
|
+
|
40
|
+
end # type maker method
|
41
|
+
|
42
|
+
|
43
|
+
shared_examples "make type" do | args: [],
|
44
|
+
accepts: [],
|
45
|
+
rejects: [],
|
46
|
+
to_data: {},
|
47
|
+
from_s: nil,
|
48
|
+
**expectations |
|
49
|
+
context "#call #{ args.map(&:inspect).join ', ' }" do
|
37
50
|
# Load the type into the subject by applying the parent scope subject,
|
38
51
|
# which should be the Type maker method that we want to test, to the
|
39
52
|
# args we received.
|
40
|
-
|
53
|
+
subject{ super().call *args }
|
41
54
|
|
42
55
|
# Expect that it's a {NRSER::Types::Type} and any other expectations that
|
43
56
|
# may have been passed in.
|
@@ -45,19 +58,21 @@ shared_examples "Type maker method" do | args: [],
|
|
45
58
|
{ to: { be_a: NRSER::Types::Type } },
|
46
59
|
*expectations.values
|
47
60
|
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
+
describe "#test" do
|
62
|
+
# Make sure it accepts the accepts
|
63
|
+
accepts.each { |value|
|
64
|
+
it "accepts #{ value.inspect }" do
|
65
|
+
expect( subject.test value ).to be true
|
66
|
+
end
|
67
|
+
}
|
68
|
+
|
69
|
+
# And that it rejects the rejects
|
70
|
+
rejects.each { |value|
|
71
|
+
it "rejects #{ value.inspect }" do
|
72
|
+
expect( subject.test value ).to be false
|
73
|
+
end
|
74
|
+
}
|
75
|
+
end # #test
|
61
76
|
|
62
77
|
# {NRSER::Types::Type#to_data} tests
|
63
78
|
to_data.each { |value, data|
|
@@ -65,7 +80,41 @@ shared_examples "Type maker method" do | args: [],
|
|
65
80
|
expect( subject.to_data value ).to eq data
|
66
81
|
end
|
67
82
|
}
|
68
|
-
|
83
|
+
|
84
|
+
# {NRSER::Types::Type.from_s} test
|
85
|
+
unless from_s.nil?
|
86
|
+
describe '#from_s' do
|
87
|
+
|
88
|
+
if from_s.key? :accepts
|
89
|
+
context "accepts" do
|
90
|
+
from_s[:accepts].each { |s, expected|
|
91
|
+
describe s.inspect do
|
92
|
+
subject { super().from_s s }
|
93
|
+
|
94
|
+
it { is_expected.to eq expected }
|
95
|
+
end
|
96
|
+
} # each
|
97
|
+
end # accepts
|
98
|
+
end
|
99
|
+
|
100
|
+
if from_s.key? :rejects
|
101
|
+
context "rejects" do
|
102
|
+
from_s[:rejects].each { |s, error|
|
103
|
+
describe s.inspect do
|
104
|
+
it "raises an error" do
|
105
|
+
expect {
|
106
|
+
subject.from_s s
|
107
|
+
}.to raise_error *NRSER.as_array( error )
|
108
|
+
end # raises an error
|
109
|
+
end #
|
110
|
+
}
|
111
|
+
end # rejects
|
112
|
+
end
|
113
|
+
|
114
|
+
end # #from_s
|
115
|
+
end # unless from_s.nil?
|
116
|
+
|
117
|
+
end # #call( ... )
|
69
118
|
end # Type maker method
|
70
119
|
|
71
120
|
|