nrser 0.0.26 → 0.0.27

Sign up to get free protection for your applications and to get access to all the features.
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