nrser 0.0.26 → 0.0.27
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.
- 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
|