nrser 0.0.26 → 0.0.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/nrser.rb +1 -0
- data/lib/nrser/array.rb +15 -0
- data/lib/nrser/binding.rb +7 -1
- data/lib/nrser/enumerable.rb +21 -1
- data/lib/nrser/errors.rb +56 -6
- data/lib/nrser/hash/deep_merge.rb +1 -1
- data/lib/nrser/message.rb +33 -0
- data/lib/nrser/meta/props.rb +77 -15
- data/lib/nrser/meta/props/prop.rb +276 -44
- data/lib/nrser/proc.rb +7 -3
- data/lib/nrser/refinements/array.rb +5 -0
- data/lib/nrser/refinements/enumerable.rb +5 -0
- data/lib/nrser/refinements/hash.rb +8 -0
- data/lib/nrser/refinements/object.rb +11 -1
- data/lib/nrser/refinements/string.rb +17 -3
- data/lib/nrser/refinements/symbol.rb +8 -0
- data/lib/nrser/refinements/tree.rb +22 -0
- data/lib/nrser/rspex.rb +312 -70
- data/lib/nrser/rspex/shared_examples.rb +116 -0
- data/lib/nrser/string.rb +159 -27
- data/lib/nrser/temp/unicode_math.rb +48 -0
- data/lib/nrser/text.rb +3 -0
- data/lib/nrser/text/indentation.rb +210 -0
- data/lib/nrser/text/lines.rb +52 -0
- data/lib/nrser/text/word_wrap.rb +29 -0
- data/lib/nrser/tree.rb +4 -78
- data/lib/nrser/tree/each_branch.rb +76 -0
- data/lib/nrser/tree/map_branches.rb +91 -0
- data/lib/nrser/tree/map_tree.rb +97 -0
- data/lib/nrser/tree/transform.rb +56 -13
- data/lib/nrser/types.rb +1 -0
- data/lib/nrser/types/array.rb +15 -3
- data/lib/nrser/types/is_a.rb +40 -1
- data/lib/nrser/types/nil.rb +17 -0
- data/lib/nrser/types/paths.rb +17 -2
- data/lib/nrser/types/strings.rb +57 -22
- data/lib/nrser/types/tuples.rb +5 -0
- data/lib/nrser/types/type.rb +47 -6
- data/lib/nrser/version.rb +1 -1
- data/spec/nrser/errors/abstract_method_error_spec.rb +46 -0
- data/spec/nrser/meta/props/to_and_from_data_spec.rb +74 -0
- data/spec/nrser/meta/props_spec.rb +6 -2
- data/spec/nrser/refinements/erb_spec.rb +100 -1
- data/spec/nrser/{common_prefix_spec.rb → string/common_prefix_spec.rb} +9 -0
- data/spec/nrser/text/dedent_spec.rb +80 -0
- data/spec/nrser/tree/map_branch_spec.rb +83 -0
- data/spec/nrser/tree/map_tree_spec.rb +123 -0
- data/spec/nrser/tree/transform_spec.rb +26 -29
- data/spec/nrser/tree/transformer_spec.rb +179 -0
- data/spec/nrser/types/paths_spec.rb +73 -45
- data/spec/spec_helper.rb +10 -0
- metadata +27 -7
- data/spec/nrser/dedent_spec.rb +0 -36
@@ -16,7 +16,8 @@ describe NRSER::Meta::Props do
|
|
16
16
|
|
17
17
|
let(:point_class) {
|
18
18
|
Class.new(NRSER::Meta::Props::Base) do
|
19
|
-
#
|
19
|
+
# So that error messages look right
|
20
|
+
def self.name; 'Point'; end
|
20
21
|
|
21
22
|
prop :x, type: t.int
|
22
23
|
prop :y, type: t.int
|
@@ -137,7 +138,10 @@ describe NRSER::Meta::Props do
|
|
137
138
|
),
|
138
139
|
},
|
139
140
|
raising: {
|
140
|
-
[{x: 1, y: 'why?'}] => [
|
141
|
+
[ {x: 1, y: 'why?'} ] => [
|
142
|
+
TypeError,
|
143
|
+
/Value of type String for prop Point\#y\s+failed type check/m
|
144
|
+
],
|
141
145
|
}
|
142
146
|
end # .new
|
143
147
|
|
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'nrser/refinements'
|
3
2
|
|
3
|
+
require 'nrser/refinements'
|
4
4
|
using NRSER
|
5
5
|
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
require 'nrser/meta/props'
|
10
|
+
|
6
11
|
describe 'Binding#erb' do
|
7
12
|
it "refines NRSER.erb into Binding" do
|
8
13
|
expect(
|
@@ -25,6 +30,100 @@ describe 'Binding#erb' do
|
|
25
30
|
x is 1
|
26
31
|
BLOCK
|
27
32
|
end
|
33
|
+
|
34
|
+
|
35
|
+
it "dedents before interpolating" do
|
36
|
+
dump = JSON.pretty_generate(
|
37
|
+
{
|
38
|
+
x: 1,
|
39
|
+
}
|
40
|
+
)
|
41
|
+
|
42
|
+
expected = <<-END
|
43
|
+
dump is:
|
44
|
+
|
45
|
+
{
|
46
|
+
"x": 1
|
47
|
+
}
|
48
|
+
|
49
|
+
END
|
50
|
+
|
51
|
+
expect(
|
52
|
+
binding.erb <<-END
|
53
|
+
dump is:
|
54
|
+
|
55
|
+
<%= dump %>
|
56
|
+
|
57
|
+
END
|
58
|
+
).to eq expected
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
it "preserves indent" do
|
63
|
+
dump = JSON.pretty_generate(
|
64
|
+
{
|
65
|
+
x: 1,
|
66
|
+
}
|
67
|
+
)
|
68
|
+
|
69
|
+
expected = <<-END
|
70
|
+
dump is:
|
71
|
+
|
72
|
+
{
|
73
|
+
"x": 1
|
74
|
+
}
|
75
|
+
|
76
|
+
END
|
77
|
+
|
78
|
+
expect(
|
79
|
+
binding.erb %{
|
80
|
+
dump is:
|
81
|
+
|
82
|
+
<%= dump %>
|
83
|
+
|
84
|
+
}
|
85
|
+
).to eq expected
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
it "works on a real-world example" do
|
90
|
+
ERBSpecTester = Class.new( NRSER::Meta::Props::Base ) do
|
91
|
+
prop :x, type: t.int, from_data: {hey: 'ho', lets: 'go!'}
|
92
|
+
end
|
93
|
+
|
94
|
+
prop = ERBSpecTester.props[:x]
|
95
|
+
|
96
|
+
error = begin
|
97
|
+
prop.value_from_data "I'M DATA!"
|
98
|
+
rescue TypeError => e
|
99
|
+
e
|
100
|
+
end
|
101
|
+
|
102
|
+
expect( error.message ).
|
103
|
+
to eq <<-END
|
104
|
+
Expected `@from_data` to be Symbol, String or Proc;
|
105
|
+
found Hash.
|
106
|
+
|
107
|
+
Acceptable types:
|
108
|
+
|
109
|
+
- Symbol or String
|
110
|
+
- Name of class method on the class this property is defined in
|
111
|
+
(ERBSpecTester) to call with data to convert it to a
|
112
|
+
property value.
|
113
|
+
|
114
|
+
- Proc
|
115
|
+
- Procedure to call with data to convert it to a property value.
|
116
|
+
|
117
|
+
Found `@from_data`:
|
118
|
+
|
119
|
+
{:hey=>"ho", :lets=>"go!"}
|
120
|
+
|
121
|
+
(type Hash)
|
122
|
+
|
123
|
+
END
|
124
|
+
|
125
|
+
end
|
126
|
+
|
28
127
|
|
29
128
|
it "handles edge cases" do
|
30
129
|
expect( binding.erb '' ).to eq ''
|
@@ -27,4 +27,13 @@ describe "NRSER.common_prefix" do
|
|
27
27
|
BLOCK
|
28
28
|
).to eq " "
|
29
29
|
end
|
30
|
+
|
31
|
+
it "finds indents in %-quoted strings" do
|
32
|
+
str = %|
|
33
|
+
hey
|
34
|
+
there
|
35
|
+
|.lines.reject( &NRSER.method( :whitespace? ) ).join
|
36
|
+
|
37
|
+
expect( NRSER.common_prefix str.lines ).to eq ' '
|
38
|
+
end
|
30
39
|
end # common_prefix
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe_method "NRSER.dedent" do
|
4
|
+
subject { NRSER.method :dedent }
|
5
|
+
|
6
|
+
let( :lines ) {
|
7
|
+
[
|
8
|
+
"def f x",
|
9
|
+
" x * x",
|
10
|
+
"end",
|
11
|
+
""
|
12
|
+
]
|
13
|
+
}
|
14
|
+
|
15
|
+
let( :joined ) {
|
16
|
+
lines.join("\n")
|
17
|
+
}
|
18
|
+
|
19
|
+
it "removes indents" do
|
20
|
+
expect(
|
21
|
+
NRSER.dedent <<-BLOCK
|
22
|
+
def f x
|
23
|
+
x * x
|
24
|
+
end
|
25
|
+
BLOCK
|
26
|
+
).to eq joined
|
27
|
+
end
|
28
|
+
|
29
|
+
it "ignores things it that aren't indented" do
|
30
|
+
expect( NRSER.dedent joined ).to eq joined
|
31
|
+
end
|
32
|
+
|
33
|
+
it "handles edge cases" do
|
34
|
+
expect( NRSER.dedent '' ).to eq ''
|
35
|
+
expect( NRSER.dedent 'blah' ).to eq 'blah'
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
context "%-quoted multi-line string" do
|
40
|
+
|
41
|
+
subject {
|
42
|
+
%|
|
43
|
+
def f x
|
44
|
+
x * x
|
45
|
+
end
|
46
|
+
|
|
47
|
+
}
|
48
|
+
|
49
|
+
it {
|
50
|
+
is_expected.to eq [
|
51
|
+
"",
|
52
|
+
" def f x",
|
53
|
+
" x * x",
|
54
|
+
" end",
|
55
|
+
" ",
|
56
|
+
].join( "\n" )
|
57
|
+
}
|
58
|
+
|
59
|
+
describe "#lines" do
|
60
|
+
subject { super().lines }
|
61
|
+
it { is_expected.to eq [
|
62
|
+
"\n",
|
63
|
+
" def f x\n",
|
64
|
+
" x * x\n",
|
65
|
+
" end\n",
|
66
|
+
" ",
|
67
|
+
] }
|
68
|
+
end # #lines
|
69
|
+
|
70
|
+
|
71
|
+
describe "dedent applied" do
|
72
|
+
subject { NRSER.dedent super() }
|
73
|
+
|
74
|
+
it { is_expected.to eq "\n" + joined }
|
75
|
+
end # "dedent"
|
76
|
+
|
77
|
+
|
78
|
+
end # %-quoted multi-line strings
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
describe "NRSER.map_branches" do
|
7
|
+
# ========================================================================
|
8
|
+
|
9
|
+
subject { NRSER.method :map_branches }
|
10
|
+
|
11
|
+
context "called without a block" do
|
12
|
+
# ========================================================================
|
13
|
+
|
14
|
+
it "raises an error" do
|
15
|
+
expect { subject.call [1, 2, 3] }.to raise_error ArgumentError
|
16
|
+
end
|
17
|
+
|
18
|
+
end # called without a block
|
19
|
+
# ************************************************************************
|
20
|
+
|
21
|
+
|
22
|
+
context "called with a block" do
|
23
|
+
# ========================================================================
|
24
|
+
|
25
|
+
context "called with arrays" do
|
26
|
+
# ========================================================================
|
27
|
+
|
28
|
+
context_where tree: [1, 2, 3] do
|
29
|
+
context "square values" do
|
30
|
+
subject {
|
31
|
+
super().call( [1, 2, 3] ) { |index, value| [index, value * value] }
|
32
|
+
}
|
33
|
+
|
34
|
+
it { is_expected.to eq [1, 4, 9] }
|
35
|
+
end # [1, 2, 3] => v * v
|
36
|
+
end # tree: [1, 2, 3]
|
37
|
+
|
38
|
+
|
39
|
+
context_where tree: [:a, :b] do
|
40
|
+
context "swap values (totally contrived example)" do
|
41
|
+
# Don't actually swap like this, but tests how I think it works
|
42
|
+
|
43
|
+
subject {
|
44
|
+
super().call( tree) { |index, value|
|
45
|
+
[(index + 1) % 2, value]
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
it { is_expected.to eq [:b, :a] }
|
50
|
+
end # [1, 2, 3] => v * v
|
51
|
+
end # tree: [:a, :b]
|
52
|
+
|
53
|
+
|
54
|
+
end # called with arrays
|
55
|
+
# ************************************************************************
|
56
|
+
|
57
|
+
|
58
|
+
context "called with hashes" do
|
59
|
+
# ========================================================================
|
60
|
+
|
61
|
+
context_where tree: {x: 'ex', y: 'why?'} do
|
62
|
+
|
63
|
+
describe "map keys to string #ord" do
|
64
|
+
subject {
|
65
|
+
super().call( tree ) { |key, value|
|
66
|
+
[key.to_s.ord, value]
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
it { is_expected.to eq 120 => 'ex', 121 => 'why?' }
|
71
|
+
end
|
72
|
+
|
73
|
+
end # tree: {x: 'ex', y: 'why?'}
|
74
|
+
|
75
|
+
|
76
|
+
end # called with hashes
|
77
|
+
# ************************************************************************
|
78
|
+
|
79
|
+
end # called with a block
|
80
|
+
# ************************************************************************
|
81
|
+
|
82
|
+
end # NRSER.map_branches
|
83
|
+
# ************************************************************************
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
describe_method "NRSER.map_tree" do
|
7
|
+
# ========================================================================
|
8
|
+
|
9
|
+
subject { NRSER.method :map_tree }
|
10
|
+
|
11
|
+
describe_section "Simple Examples" do
|
12
|
+
# ========================================================================
|
13
|
+
|
14
|
+
context_where(
|
15
|
+
tree: {
|
16
|
+
1 => {
|
17
|
+
name: 'Mr. Neil',
|
18
|
+
fav_color: 'blue',
|
19
|
+
age: 33,
|
20
|
+
likes: [:tacos, :cats],
|
21
|
+
},
|
22
|
+
|
23
|
+
2 => {
|
24
|
+
name: 'Ms. Mica',
|
25
|
+
fav_color: 'red',
|
26
|
+
age: 32,
|
27
|
+
likes: [:cats, :cookies],
|
28
|
+
},
|
29
|
+
}
|
30
|
+
) do
|
31
|
+
describe "Convert all Integers to Strings" do
|
32
|
+
|
33
|
+
subject {
|
34
|
+
super().call( tree ) { |element|
|
35
|
+
if element.is_a? Integer
|
36
|
+
element.to_s
|
37
|
+
else
|
38
|
+
element
|
39
|
+
end
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
it {
|
44
|
+
is_expected.to eq \
|
45
|
+
'1' => {
|
46
|
+
name: 'Mr. Neil',
|
47
|
+
fav_color: 'blue',
|
48
|
+
age: '33',
|
49
|
+
likes: [:tacos, :cats],
|
50
|
+
},
|
51
|
+
|
52
|
+
'2' => {
|
53
|
+
name: 'Ms. Mica',
|
54
|
+
fav_color: 'red',
|
55
|
+
age: '32',
|
56
|
+
likes: [:cats, :cookies],
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
end # Convert all Integers to Strings
|
62
|
+
end # context where
|
63
|
+
|
64
|
+
end # section Simple Examples
|
65
|
+
# ************************************************************************
|
66
|
+
|
67
|
+
|
68
|
+
describe_section "pruning" do
|
69
|
+
# ========================================================================
|
70
|
+
|
71
|
+
context_where(
|
72
|
+
tree: {
|
73
|
+
1 => {
|
74
|
+
name: 'Mr. Neil',
|
75
|
+
fav_color?: nil,
|
76
|
+
age: 33,
|
77
|
+
likes: [:tacos, :cats],
|
78
|
+
},
|
79
|
+
|
80
|
+
2 => {
|
81
|
+
name: 'Ms. Mica',
|
82
|
+
fav_color?: 'red',
|
83
|
+
age: 32,
|
84
|
+
likes: [:cats, :cookies],
|
85
|
+
},
|
86
|
+
}
|
87
|
+
) do
|
88
|
+
describe "Convert all Integers to Strings and prune" do
|
89
|
+
|
90
|
+
subject {
|
91
|
+
super().call( tree, prune: true ) { |element|
|
92
|
+
if element.is_a? Integer
|
93
|
+
element.to_s
|
94
|
+
else
|
95
|
+
element
|
96
|
+
end
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
it {
|
101
|
+
is_expected.to eq \
|
102
|
+
'1' => {
|
103
|
+
name: 'Mr. Neil',
|
104
|
+
age: '33',
|
105
|
+
likes: [:tacos, :cats],
|
106
|
+
},
|
107
|
+
|
108
|
+
'2' => {
|
109
|
+
name: 'Ms. Mica',
|
110
|
+
fav_color: 'red',
|
111
|
+
age: '32',
|
112
|
+
likes: [:cats, :cookies],
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
end # Convert all Integers to Strings
|
117
|
+
end # context where
|
118
|
+
|
119
|
+
end # section pruning
|
120
|
+
# ************************************************************************
|
121
|
+
|
122
|
+
|
123
|
+
end # NRSER.map_tree
|
@@ -60,35 +60,32 @@ describe "NRSER.transform" do
|
|
60
60
|
|
61
61
|
end # transform in key
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
#
|
89
|
-
# ]
|
90
|
-
# end
|
91
|
-
# end # arrays in tree
|
63
|
+
|
64
|
+
describe "arrays in tree" do
|
65
|
+
let :tree do
|
66
|
+
{
|
67
|
+
list: [
|
68
|
+
{ name: :name.rtvr },
|
69
|
+
{ age: :age.rtvr },
|
70
|
+
]
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
let :source do
|
75
|
+
{
|
76
|
+
name: 'Mr. Cat',
|
77
|
+
age: 2,
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
it do
|
82
|
+
is_expected.to eq \
|
83
|
+
list: [
|
84
|
+
{ name: 'Mr. Cat' },
|
85
|
+
{ age: 2 },
|
86
|
+
]
|
87
|
+
end
|
88
|
+
end # arrays in tree
|
92
89
|
|
93
90
|
|
94
91
|
end # section simple examples
|