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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nrser.rb +1 -0
  3. data/lib/nrser/array.rb +15 -0
  4. data/lib/nrser/binding.rb +7 -1
  5. data/lib/nrser/enumerable.rb +21 -1
  6. data/lib/nrser/errors.rb +56 -6
  7. data/lib/nrser/hash/deep_merge.rb +1 -1
  8. data/lib/nrser/message.rb +33 -0
  9. data/lib/nrser/meta/props.rb +77 -15
  10. data/lib/nrser/meta/props/prop.rb +276 -44
  11. data/lib/nrser/proc.rb +7 -3
  12. data/lib/nrser/refinements/array.rb +5 -0
  13. data/lib/nrser/refinements/enumerable.rb +5 -0
  14. data/lib/nrser/refinements/hash.rb +8 -0
  15. data/lib/nrser/refinements/object.rb +11 -1
  16. data/lib/nrser/refinements/string.rb +17 -3
  17. data/lib/nrser/refinements/symbol.rb +8 -0
  18. data/lib/nrser/refinements/tree.rb +22 -0
  19. data/lib/nrser/rspex.rb +312 -70
  20. data/lib/nrser/rspex/shared_examples.rb +116 -0
  21. data/lib/nrser/string.rb +159 -27
  22. data/lib/nrser/temp/unicode_math.rb +48 -0
  23. data/lib/nrser/text.rb +3 -0
  24. data/lib/nrser/text/indentation.rb +210 -0
  25. data/lib/nrser/text/lines.rb +52 -0
  26. data/lib/nrser/text/word_wrap.rb +29 -0
  27. data/lib/nrser/tree.rb +4 -78
  28. data/lib/nrser/tree/each_branch.rb +76 -0
  29. data/lib/nrser/tree/map_branches.rb +91 -0
  30. data/lib/nrser/tree/map_tree.rb +97 -0
  31. data/lib/nrser/tree/transform.rb +56 -13
  32. data/lib/nrser/types.rb +1 -0
  33. data/lib/nrser/types/array.rb +15 -3
  34. data/lib/nrser/types/is_a.rb +40 -1
  35. data/lib/nrser/types/nil.rb +17 -0
  36. data/lib/nrser/types/paths.rb +17 -2
  37. data/lib/nrser/types/strings.rb +57 -22
  38. data/lib/nrser/types/tuples.rb +5 -0
  39. data/lib/nrser/types/type.rb +47 -6
  40. data/lib/nrser/version.rb +1 -1
  41. data/spec/nrser/errors/abstract_method_error_spec.rb +46 -0
  42. data/spec/nrser/meta/props/to_and_from_data_spec.rb +74 -0
  43. data/spec/nrser/meta/props_spec.rb +6 -2
  44. data/spec/nrser/refinements/erb_spec.rb +100 -1
  45. data/spec/nrser/{common_prefix_spec.rb → string/common_prefix_spec.rb} +9 -0
  46. data/spec/nrser/text/dedent_spec.rb +80 -0
  47. data/spec/nrser/tree/map_branch_spec.rb +83 -0
  48. data/spec/nrser/tree/map_tree_spec.rb +123 -0
  49. data/spec/nrser/tree/transform_spec.rb +26 -29
  50. data/spec/nrser/tree/transformer_spec.rb +179 -0
  51. data/spec/nrser/types/paths_spec.rb +73 -45
  52. data/spec/spec_helper.rb +10 -0
  53. metadata +27 -7
  54. 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
- # include NRSER::Meta::Props
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?'}] => [TypeError, /must be of type `IntType`/],
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
- # TODO doesn't work yet... prob wants a general {NRSER#map_branches} or
64
- # something that converts the map result into a Hash only if the
65
- # tree was hash-like.
66
- #
67
- # describe "arrays in tree" do
68
- # let :tree do
69
- # {
70
- # list: [
71
- # { name: :name.rtvr },
72
- # { age: :age.rtvr },
73
- # ]
74
- # }
75
- # end
76
- #
77
- # let :source do
78
- # {
79
- # name: 'Mr. Cat',
80
- # age: 2,
81
- # }
82
- # end
83
- #
84
- # it do
85
- # is_expected.to eq \
86
- # list: [
87
- # { name: 'Mr. Cat' },
88
- # { age: 2 },
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