babl-json 0.2.3 → 0.2.4

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/babl.rb +2 -2
  3. data/lib/babl/builder.rb +2 -0
  4. data/lib/babl/builder/chain_builder.rb +1 -2
  5. data/lib/babl/builder/template_base.rb +3 -4
  6. data/lib/babl/nodes.rb +15 -0
  7. data/lib/babl/nodes/create_pin.rb +1 -2
  8. data/lib/babl/nodes/dep.rb +1 -2
  9. data/lib/babl/nodes/each.rb +2 -2
  10. data/lib/babl/nodes/fixed_array.rb +2 -3
  11. data/lib/babl/nodes/goto_pin.rb +1 -2
  12. data/lib/babl/nodes/internal_value.rb +1 -1
  13. data/lib/babl/nodes/merge.rb +14 -35
  14. data/lib/babl/nodes/nav.rb +1 -1
  15. data/lib/babl/nodes/object.rb +5 -4
  16. data/lib/babl/nodes/parent.rb +1 -2
  17. data/lib/babl/nodes/static.rb +2 -3
  18. data/lib/babl/nodes/switch.rb +2 -3
  19. data/lib/babl/nodes/terminal_value.rb +17 -12
  20. data/lib/babl/nodes/typed.rb +2 -2
  21. data/lib/babl/nodes/with.rb +1 -2
  22. data/lib/babl/operators.rb +21 -0
  23. data/lib/babl/operators/array.rb +1 -2
  24. data/lib/babl/operators/dep.rb +1 -1
  25. data/lib/babl/operators/each.rb +1 -1
  26. data/lib/babl/operators/enter.rb +1 -0
  27. data/lib/babl/operators/merge.rb +1 -2
  28. data/lib/babl/operators/nav.rb +1 -1
  29. data/lib/babl/operators/object.rb +1 -2
  30. data/lib/babl/operators/parent.rb +1 -1
  31. data/lib/babl/operators/partial.rb +1 -1
  32. data/lib/babl/operators/pin.rb +2 -3
  33. data/lib/babl/operators/static.rb +3 -3
  34. data/lib/babl/operators/switch.rb +1 -3
  35. data/lib/babl/operators/typed.rb +1 -1
  36. data/lib/babl/operators/with.rb +1 -2
  37. data/lib/babl/rendering.rb +3 -0
  38. data/lib/babl/rendering/compiled_template.rb +2 -2
  39. data/lib/babl/schema.rb +7 -0
  40. data/lib/babl/schema/any_of.rb +43 -38
  41. data/lib/babl/schema/dyn_array.rb +1 -1
  42. data/lib/babl/schema/fixed_array.rb +1 -1
  43. data/lib/babl/schema/object.rb +1 -1
  44. data/lib/babl/schema/static.rb +1 -1
  45. data/lib/babl/schema/typed.rb +1 -1
  46. data/lib/babl/template.rb +2 -23
  47. data/lib/babl/utils.rb +3 -0
  48. data/lib/babl/version.rb +1 -1
  49. metadata +9 -63
  50. data/.gitignore +0 -3
  51. data/.rubocop.yml +0 -201
  52. data/.ruby-version +0 -1
  53. data/.travis.yml +0 -4
  54. data/CHANGELOG.md +0 -36
  55. data/Gemfile +0 -5
  56. data/LICENSE +0 -7
  57. data/README.md +0 -89
  58. data/babl.gemspec +0 -24
  59. data/logo-babl.png +0 -0
  60. data/spec/operators/array_spec.rb +0 -37
  61. data/spec/operators/call_spec.rb +0 -64
  62. data/spec/operators/continue_spec.rb +0 -25
  63. data/spec/operators/default_spec.rb +0 -15
  64. data/spec/operators/dep_spec.rb +0 -15
  65. data/spec/operators/each_spec.rb +0 -42
  66. data/spec/operators/enter_spec.rb +0 -28
  67. data/spec/operators/extends_spec.rb +0 -30
  68. data/spec/operators/merge_spec.rb +0 -124
  69. data/spec/operators/nav_spec.rb +0 -71
  70. data/spec/operators/null_spec.rb +0 -15
  71. data/spec/operators/nullable_spec.rb +0 -29
  72. data/spec/operators/object_spec.rb +0 -30
  73. data/spec/operators/parent_spec.rb +0 -50
  74. data/spec/operators/partial_spec.rb +0 -36
  75. data/spec/operators/pin_spec.rb +0 -172
  76. data/spec/operators/source_spec.rb +0 -33
  77. data/spec/operators/static_spec.rb +0 -27
  78. data/spec/operators/switch_spec.rb +0 -151
  79. data/spec/operators/typed_spec.rb +0 -84
  80. data/spec/operators/with_spec.rb +0 -31
  81. data/spec/spec_helper.rb +0 -2
  82. data/spec/spec_helper/operator_testing.rb +0 -46
  83. data/spec/spec_helper/schema_utils.rb +0 -53
  84. data/spec/utils/value_spec.rb +0 -54
@@ -1,124 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Merge do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#merge' do
7
- context 'merge two objects' do
8
- template {
9
- merge(
10
- object(a: static('A')),
11
- b: _
12
- )
13
- }
14
-
15
- let(:object) { { b: 42 } }
16
-
17
- it { expect(json).to eq('a' => 'A', 'b' => 42) }
18
- it { expect(dependencies).to eq(b: {}) }
19
- it {
20
- expect(schema).to eq(
21
- s_object(
22
- s_property(:a, s_static('A')),
23
- s_property(:b, s_anything)
24
- )
25
- )
26
- }
27
- end
28
-
29
- context 'merge inside object' do
30
- template { object(toto: merge(_, lol: 42)) }
31
-
32
- let(:object) { { toto: { cool: 'ouai' } } }
33
-
34
- it { expect(json).to eq('toto' => { 'lol' => 42, 'cool' => 'ouai' }) }
35
- it {
36
- expect(schema).to eq(
37
- s_object(
38
- s_property(:toto,
39
- s_object(
40
- s_property(:lol, s_static(42)),
41
- additional: true
42
- ))
43
- )
44
- )
45
- }
46
- end
47
-
48
- context 'merge nothing' do
49
- template { merge }
50
-
51
- it { expect(json).to eq({}) }
52
- it { expect(schema).to eq s_object }
53
- end
54
-
55
- context 'merge that could fail in some case' do
56
- template {
57
- merge(
58
- switch(
59
- false => switch(
60
- true => {},
61
- default => 'not an object'
62
- ),
63
- default => {}
64
- ),
65
- object(test: 1)
66
- )
67
- }
68
-
69
- it { expect { schema }.to raise_error Babl::Errors::InvalidTemplate }
70
- end
71
-
72
- context 'merge only one static value' do
73
- template { merge(42) }
74
-
75
- it { expect { schema }.to raise_error Babl::Errors::InvalidTemplate }
76
- end
77
-
78
- context 'merge only one dynamic value' do
79
- template { merge(itself) }
80
-
81
- let(:object) { 43 }
82
-
83
- it { expect { json }.to raise_error Babl::Errors::RenderingError }
84
- it { expect(schema).to eq s_object(additional: true) }
85
- end
86
-
87
- context 'merge object with static' do
88
- template { merge(object(a: 1), static(b: 2)) }
89
-
90
- it { expect(json).to eq('a' => 1, 'b' => 2) }
91
- it { expect(schema).to eq s_object(s_property(:a, s_static(1)), s_property(:b, s_static(2))) }
92
- end
93
-
94
- context 'merge object with conditionally present properties' do
95
- template {
96
- merge(
97
- switch(
98
- itself => object(a: 1, b: 2),
99
- default => object(b: 3, c: 4)
100
- ),
101
- itself,
102
- switch(
103
- itself => object(c: 7),
104
- default => object(c: 5)
105
- )
106
- )
107
- }
108
-
109
- let(:object) { { b: 1 } }
110
-
111
- it { expect(json).to eq('a' => 1, 'b' => 1, 'c' => 7) }
112
- it {
113
- expect(schema).to eq(
114
- s_object(
115
- s_property(:a, s_any_of(s_anything, s_static(1)), required: false),
116
- s_property(:b, s_any_of(s_anything, s_static(2), s_static(3))),
117
- s_property(:c, s_any_of(s_static(7), s_static(5))),
118
- additional: true
119
- )
120
- )
121
- }
122
- end
123
- end
124
- end
@@ -1,71 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Nav do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#nav' do
7
- template { nav(:a) }
8
-
9
- context 'hash navigation' do
10
- let(:object) { { a: '42' } }
11
- it { expect(json).to eq('42') }
12
- it { expect(dependencies).to eq(a: {}) }
13
-
14
- context 'method navigation propagate dependency chain' do
15
- template { nav(:a).nav(:to_i) }
16
- it { expect(json).to eq(42) }
17
- it { expect(dependencies).to eq(a: { to_i: {} }) }
18
- end
19
- end
20
-
21
- context 'navigate to non serializable' do
22
- template { nav(:a) }
23
- let(:object) { { a: :test } }
24
- it { expect { json }.to raise_error Babl::Errors::RenderingError }
25
- end
26
-
27
- context 'navigate to non serializable in nested object' do
28
- template { nav(:a) }
29
- let(:object) { { a: { b: [1, 2, { c: 1, d: Object.new }] } } }
30
- it { expect { json }.to raise_error Babl::Errors::RenderingError, /\__root__\.a\.b\.2\.d/ }
31
- end
32
-
33
- context 'navigate to non serializable in nested object with invalid key' do
34
- template { nav(:a) }
35
- let(:object) { { a: { b: [1, 2, { c: 1, Object.new => 1 }] } } }
36
- it { expect { json }.to raise_error Babl::Errors::RenderingError, /\__root__\.a\.b\.2/ }
37
- end
38
-
39
- context 'object navigation' do
40
- let(:object) { Struct.new(:a).new(42) }
41
- it { expect(json).to eq(42) }
42
- it { expect(dependencies).to eq(a: {}) }
43
- end
44
-
45
- context 'block navigation' do
46
- template { nav { |x| x * 2 } }
47
-
48
- let(:object) { 42 }
49
-
50
- it { expect(json).to eq(84) }
51
- it { expect(dependencies).to eq({}) }
52
-
53
- context 'block navigation breaks dependency chain' do
54
- template { nav { |x| x * 2 }.nav(:to_i) }
55
- it { expect(dependencies).to eq({}) }
56
- end
57
- end
58
-
59
- context '#nav should stop key propagation for #enter' do
60
- template { object(a: nav._) }
61
- it { expect { compiled }.to raise_error Babl::Errors::InvalidTemplate }
62
- end
63
-
64
- context 'nav to array of complex objects' do
65
- template { nav(:arr) }
66
- let(:object) { { arr: [nil, 1, 'lol', { a: [1] }, [], {}, true, false] } }
67
- it { expect(json).to eq([nil, 1, 'lol', { 'a' => [1] }, [], {}, true, false]) }
68
- it { expect(schema).to eq s_anything }
69
- end
70
- end
71
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Null do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#null' do
7
- template { { val: null } }
8
-
9
- let(:object) { {} }
10
-
11
- it { expect(schema).to eq s_object(s_property(:val, s_static(nil))) }
12
- it { expect(dependencies).to eq({}) }
13
- it { expect(json).to eq('val' => nil) }
14
- end
15
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Nullable do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#nullable' do
7
- let(:object) { { nullprop: nil, notnullprop: { abc: 12 } } }
8
-
9
- template {
10
- object(
11
- nullprop: nav(:nullprop).nullable.nav(:abc),
12
- notnullprop: nav(:notnullprop).nullable.object(:abc)
13
- )
14
- }
15
-
16
- it { expect(json).to eq('nullprop' => nil, 'notnullprop' => { 'abc' => 12 }) }
17
-
18
- it {
19
- expect(schema).to eq(
20
- s_object(
21
- s_property(:nullprop, s_anything),
22
- s_property(:notnullprop, s_any_of(s_object(s_property(:abc, s_anything)), s_null))
23
- )
24
- )
25
- }
26
-
27
- it { expect(dependencies).to eq(nullprop: { abc: {} }, notnullprop: { abc: {} }) }
28
- end
29
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Object do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#object' do
7
- template { object(:a, :b, c: _, d: nav(:d)) }
8
-
9
- let(:object) { { a: 1, b: 2, c: 3, d: 4 } }
10
-
11
- it { expect(json).to eq('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4) }
12
- it {
13
- expect(schema).to eq(
14
- s_object(
15
- s_property(:a, s_anything),
16
- s_property(:b, s_anything),
17
- s_property(:c, s_anything),
18
- s_property(:d, s_anything)
19
- )
20
- )
21
- }
22
- it { expect(dependencies).to eq(a: {}, b: {}, c: {}, d: {}) }
23
-
24
- context 'misused (chaining after object)' do
25
- template { object(:a).object(:b) }
26
-
27
- it { expect { compiled }.to raise_error Babl::Errors::InvalidTemplate }
28
- end
29
- end
30
- end
@@ -1,50 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Parent do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#parent' do
7
- context 'valid usage' do
8
- template { nav(:box).dep(:box_dep).parent.dep(:root_dep) }
9
-
10
- let(:object) { { box: 42 } }
11
-
12
- it { expect(schema).to eq s_anything }
13
- it { expect(dependencies).to eq(box: { box_dep: {} }, root_dep: {}) }
14
- it { expect(json).to eq('box' => 42) }
15
- end
16
-
17
- context 'error while navigating' do
18
- template { nav(:a).parent.nav(:a).nav(:b, :x) }
19
-
20
- let(:object) { { a: { b: { c: 56 } } } }
21
-
22
- it { expect { json }.to raise_error(/\__root__\.a\.b\.x/) }
23
- end
24
-
25
- context 'invalid usage' do
26
- template { parent }
27
-
28
- it { expect { compiled }.to raise_error Babl::Errors::InvalidTemplate }
29
- end
30
-
31
- context 'deeply nested parent chain' do
32
- template {
33
- nav(:a, :b, :c, :d, :e).parent.parent.parent.nav(:f, :g, :h).parent.parent.parent.parent.nav(:i)
34
- }
35
-
36
- it { expect(dependencies).to eq(a: { b: { f: { g: { h: {} } }, c: { d: { e: {} } } }, i: {} }) }
37
- end
38
-
39
- context 'same-level key + nested parent chain' do
40
- template {
41
- object(
42
- a: _.nav(:b, :c).parent.parent.nav(:h),
43
- b: _.nav(:a).parent.nav(:a)
44
- )
45
- }
46
-
47
- it { expect(dependencies).to eq(a: { b: { c: {} }, h: {} }, b: { a: {} }) }
48
- end
49
- end
50
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Partial do
4
- extend SpecHelper::OperatorTesting
5
-
6
- let(:custom_lookup_context) {
7
- TestLookupContext.new(
8
- blabla: TestLookupContext.new(
9
- "[partial('navi').partial('miche'), partial('muche')]",
10
-
11
- miche: TestLookupContext.new(
12
- "partial('blabla')",
13
-
14
- blabla: TestLookupContext.new('call { 1 + self }')
15
- ),
16
-
17
- muche: TestLookupContext.new('23'),
18
- navi: TestLookupContext.new(':some_property')
19
- )
20
- )
21
- }
22
- let(:dsl) { Babl::Template.new.with_lookup_context(custom_lookup_context) }
23
- let(:object) { { some_property: 12 } }
24
-
25
- context 'missing partial' do
26
- template { partial('i_do_not_exist') }
27
-
28
- it { expect { compiled }.to raise_error Babl::Errors::InvalidTemplate }
29
- end
30
-
31
- context 'found partial' do
32
- template { partial('blabla') }
33
-
34
- it { expect(json).to eq [13, 23] }
35
- end
36
- end
@@ -1,172 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Babl::Operators::Pin do
4
- extend SpecHelper::OperatorTesting
5
-
6
- describe '#pin' do
7
- context 'simple pinning' do
8
- template {
9
- nav(:a).pin { |a|
10
- nav(:b).object(
11
- x: _,
12
- y: a.nav(:y)
13
- )
14
- }
15
- }
16
-
17
- let(:object) {
18
- { a: { b: { x: 42 }, y: 13 } }
19
- }
20
-
21
- it { expect(json).to eq('x' => 42, 'y' => 13) }
22
- it { expect(dependencies).to eq(a: { y: {}, b: { x: {} } }) }
23
- it {
24
- expect(schema).to eq(
25
- s_object(
26
- s_property(:x, s_anything),
27
- s_property(:y, s_anything)
28
- )
29
- )
30
- }
31
- end
32
-
33
- context 'when visiting parent from pin' do
34
- template {
35
- nav(:a).pin { |p1|
36
- object(x: _, y: p1.parent.pin { |p2| p2.nav(:a, :b) })
37
- }
38
- }
39
-
40
- let(:object) { { a: { x: 12, b: 42 } } }
41
-
42
- it { expect(json).to eq('x' => 12, 'y' => 42) }
43
- it { expect(dependencies).to eq(a: { x: {}, b: {} }) }
44
- it {
45
- expect(schema).to eq(
46
- s_object(
47
- s_property(:x, s_anything),
48
- s_property(:y, s_anything)
49
- )
50
- )
51
- }
52
- end
53
-
54
- context 'when pinning is misused (out of context)' do
55
- template {
56
- pinref = nil
57
- object(
58
- a: pin { |p| pinref = p },
59
- b: pinref.nav(:lol)
60
- )
61
- }
62
-
63
- it { expect { compiled }.to raise_error Babl::Errors::InvalidTemplate }
64
- end
65
-
66
- context 'when pinning is mixed with a "with" context' do
67
- template {
68
- pin { |root|
69
- with(:a) { |a| a }.object(
70
- x: _,
71
- y: root.nav(:lol)
72
- )
73
- }
74
- }
75
-
76
- let(:object) { { a: { x: 34 }, lol: 1 } }
77
-
78
- it { expect(json).to eq('x' => 34, 'y' => 1) }
79
- it { expect(dependencies).to eq(a: {}, lol: {}) }
80
- it {
81
- expect(schema).to eq(
82
- s_object(
83
- s_property(:x, s_anything),
84
- s_property(:y, s_anything)
85
- )
86
- )
87
- }
88
- end
89
-
90
- context 'navigating pinning' do
91
- template {
92
- pin(:timezone) { |timezone| object(applicant: _.object(:id, tz: timezone)) }
93
- }
94
-
95
- let(:object) { { applicant: { id: 1 }, timezone: 'LA' } }
96
-
97
- it { expect(json).to eq('applicant' => { 'id' => 1, 'tz' => 'LA' }) }
98
- it { expect(dependencies).to eq(timezone: {}, applicant: { id: {} }) }
99
- it {
100
- expect(schema).to eq(
101
- s_object(
102
- s_property(:applicant,
103
- s_object(
104
- s_property(:id, s_anything),
105
- s_property(:tz, s_anything)
106
- ))
107
- )
108
- )
109
- }
110
- end
111
-
112
- context 'pin used twice in same chain' do
113
- template {
114
- nav(:a).pin { |a|
115
- object(
116
- h: nav(:h),
117
- a: a.object(
118
- x: _,
119
- y: a.nav(:lol).parent.nav(:mdr)
120
- )
121
- )
122
- }
123
- }
124
-
125
- let(:object) { { a: { h: 42, x: 13, lol: 11, mdr: 34 } } }
126
-
127
- it { expect(json).to eq('h' => 42, 'a' => { 'x' => 13, 'y' => 34 }) }
128
- it { expect(dependencies).to eq(a: { h: {}, x: {}, lol: {}, mdr: {} }) }
129
-
130
- it {
131
- expect(schema).to eq(
132
- s_object(
133
- s_property(
134
- :a,
135
- s_object(
136
- s_property(:x, s_anything),
137
- s_property(:y, s_anything)
138
- )
139
- ),
140
- s_property(:h, s_anything)
141
- )
142
- )
143
- }
144
- end
145
-
146
- context 'nested pinning' do
147
- template {
148
- pin { |root|
149
- nav(:a).pin { |a|
150
- object(
151
- a: a.nav(:x),
152
- root: root.nav(:y)
153
- )
154
- }
155
- }
156
- }
157
-
158
- let(:object) { { a: { x: 42 }, y: 13 } }
159
-
160
- it { expect(json).to eq('a' => 42, 'root' => 13) }
161
-
162
- it {
163
- expect(schema).to eq(
164
- s_object(
165
- s_property(:a, s_anything),
166
- s_property(:root, s_anything)
167
- )
168
- )
169
- }
170
- end
171
- end
172
- end