aql 0.0.1

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 (96) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +18 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.devtools +64 -0
  7. data/Guardfile +18 -0
  8. data/LICENSE +20 -0
  9. data/README.md +86 -0
  10. data/Rakefile +2 -0
  11. data/TODO +1 -0
  12. data/aql.gemspec +23 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/mutant.yml +3 -0
  16. data/config/roodi.yml +18 -0
  17. data/config/site.reek +100 -0
  18. data/config/yardstick.yml +2 -0
  19. data/examples/aql.rb +31 -0
  20. data/lib/aql.rb +62 -0
  21. data/lib/aql/buffer.rb +129 -0
  22. data/lib/aql/constants.rb +19 -0
  23. data/lib/aql/node.rb +45 -0
  24. data/lib/aql/node/attribute.rb +25 -0
  25. data/lib/aql/node/block.rb +28 -0
  26. data/lib/aql/node/call.rb +83 -0
  27. data/lib/aql/node/literal.rb +48 -0
  28. data/lib/aql/node/literal/composed.rb +10 -0
  29. data/lib/aql/node/literal/composed/document.rb +59 -0
  30. data/lib/aql/node/literal/composed/list.rb +42 -0
  31. data/lib/aql/node/literal/primitive.rb +10 -0
  32. data/lib/aql/node/literal/primitive/number.rb +28 -0
  33. data/lib/aql/node/literal/primitive/string.rb +27 -0
  34. data/lib/aql/node/literal/singleton.rb +51 -0
  35. data/lib/aql/node/name.rb +31 -0
  36. data/lib/aql/node/null.rb +21 -0
  37. data/lib/aql/node/operation.rb +20 -0
  38. data/lib/aql/node/operation/binary.rb +33 -0
  39. data/lib/aql/node/operation/for.rb +77 -0
  40. data/lib/aql/node/operation/limit.rb +42 -0
  41. data/lib/aql/node/operation/nary.rb +57 -0
  42. data/lib/aql/node/operation/unary.rb +75 -0
  43. data/lib/aql/node/operator.rb +20 -0
  44. data/lib/aql/node/operator/assignment.rb +28 -0
  45. data/lib/aql/node/operator/binary.rb +92 -0
  46. data/lib/aql/node/operator/nary.rb +48 -0
  47. data/lib/aql/node/operator/ternary.rb +30 -0
  48. data/lib/aql/node/operator/unary.rb +39 -0
  49. data/spec/shared/aql_behavior.rb +7 -0
  50. data/spec/spec_helper.rb +11 -0
  51. data/spec/support/aql_helper.rb +12 -0
  52. data/spec/unit/aql/buffer/append_spec.rb +59 -0
  53. data/spec/unit/aql/buffer/binary_spec.rb +22 -0
  54. data/spec/unit/aql/buffer/class_methods/utf8_encode_spec.rb +21 -0
  55. data/spec/unit/aql/buffer/content_spec.rb +24 -0
  56. data/spec/unit/aql/buffer/delimited_spec.rb +31 -0
  57. data/spec/unit/aql/buffer/parentheses_spec.rb +33 -0
  58. data/spec/unit/aql/buffer/wrap_delimited_spec.rb +42 -0
  59. data/spec/unit/aql/class_methods/literal_node_spec.rb +15 -0
  60. data/spec/unit/aql/class_methods/name_node_spec.rb +19 -0
  61. data/spec/unit/aql/node/attribute/aql_spec.rb +22 -0
  62. data/spec/unit/aql/node/block/aql_spec.rb +28 -0
  63. data/spec/unit/aql/node/call/aql_spec.rb +39 -0
  64. data/spec/unit/aql/node/literal/class_methods/build_spec.rb +139 -0
  65. data/spec/unit/aql/node/literal/class_methods/construct_spec.rb +16 -0
  66. data/spec/unit/aql/node/literal/class_methods/handle_spec.rb +22 -0
  67. data/spec/unit/aql/node/literal/composed/document/aql_spec.rb +32 -0
  68. data/spec/unit/aql/node/literal/composed/document/attribute/aql_spec.rb +15 -0
  69. data/spec/unit/aql/node/literal/composed/document/class_methods/construct_spec.rb +24 -0
  70. data/spec/unit/aql/node/literal/composed/list/aql_spec.rb +20 -0
  71. data/spec/unit/aql/node/literal/composed/list/class_methods/construct_spec.rb +37 -0
  72. data/spec/unit/aql/node/literal/primitive/number/aql_spec.rb +23 -0
  73. data/spec/unit/aql/node/literal/primitive/string/aql_spec.rb +21 -0
  74. data/spec/unit/aql/node/literal/singleton/aql_spec.rb +14 -0
  75. data/spec/unit/aql/node/literal/singleton/class_methods/construct_spec.rb +30 -0
  76. data/spec/unit/aql/node/name/aql_spec.rb +33 -0
  77. data/spec/unit/aql/node/null/aql_spec.rb +7 -0
  78. data/spec/unit/aql/node/operation/binary/let/aql_spec.rb +10 -0
  79. data/spec/unit/aql/node/operation/for/aql_spec.rb +18 -0
  80. data/spec/unit/aql/node/operation/keyword_spec.rb +16 -0
  81. data/spec/unit/aql/node/operation/limit/aql_spec.rb +19 -0
  82. data/spec/unit/aql/node/operation/nary/aql_spec.rb +16 -0
  83. data/spec/unit/aql/node/operation/nary/collect/into/aql_spec.rb +11 -0
  84. data/spec/unit/aql/node/operation/nary/sort/aql_spec.rb +22 -0
  85. data/spec/unit/aql/node/operation/unary/aql_spec.rb +12 -0
  86. data/spec/unit/aql/node/operation/unary/direction/aql_spec.rb +14 -0
  87. data/spec/unit/aql/node/operation/unary/filter/aql_spec.rb +20 -0
  88. data/spec/unit/aql/node/operation/unary/return/aql_spec.rb +17 -0
  89. data/spec/unit/aql/node/operator/assignment/aql_spec.rb +10 -0
  90. data/spec/unit/aql/node/operator/binary/aql_spec.rb +15 -0
  91. data/spec/unit/aql/node/operator/nary/aql_spec.rb +31 -0
  92. data/spec/unit/aql/node/operator/operator_spec.rb +18 -0
  93. data/spec/unit/aql/node/operator/ternary/aql_spec.rb +12 -0
  94. data/spec/unit/aql/node/operator/unary/aql_spec.rb +12 -0
  95. data/spec/unit/aql/node/visit_spec.rb +27 -0
  96. metadata +262 -0
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '.utf8_encode' do
4
+ let(:object) { described_class }
5
+
6
+ unless defined?(Encoding)
7
+ before do
8
+ pending "No support for encodings under #{Devtools.rvm}"
9
+ end
10
+ end
11
+
12
+ subject { object.utf8_encode(input) }
13
+
14
+ let(:input) { mock('Input') }
15
+ let(:output) { mock('Output') }
16
+
17
+ it 'should modify input encoding' do
18
+ input.should_receive(:encode).with(Encoding::UTF_8).and_return(output)
19
+ should be(output)
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '#content' do
4
+ let(:object) { described_class.new }
5
+
6
+ subject { object.content }
7
+
8
+ context 'when empty' do
9
+
10
+ it { should eql('') }
11
+
12
+ its(:frozen?) { should be(true) }
13
+
14
+ end
15
+
16
+ context 'when something was emitted' do
17
+ before do
18
+ object.append('foo').append('bar')
19
+ end
20
+
21
+ it { should eql('foobar') }
22
+ its(:frozen?) { should be(true) }
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '#delimited' do
4
+ let(:object) { described_class.new }
5
+
6
+ subject { object.delimited(nodes) }
7
+
8
+ context 'with empty nodes' do
9
+ let(:nodes) { [] }
10
+
11
+ its(:content) { should eql('') }
12
+
13
+ it_should_behave_like 'a command method'
14
+ end
15
+
16
+ context 'with one argument' do
17
+ let(:nodes) { [AQL::Node::Literal.build(1)] }
18
+
19
+ its(:content) { should eql('1') }
20
+
21
+ it_should_behave_like 'a command method'
22
+ end
23
+
24
+ context 'with multiple argments' do
25
+ let(:nodes) { [AQL::Node::Literal.build(1), AQL::Node::Literal.build(2)] }
26
+
27
+ its(:content) { should eql('1, 2') }
28
+
29
+ it_should_behave_like 'a command method'
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '#parentheses' do
4
+ let(:object) { described_class.new }
5
+
6
+ subject { object.parentheses(*arguments, &block) }
7
+
8
+ let(:block) { proc { object.append('foo') } }
9
+
10
+ context 'without arguments' do
11
+ let(:arguments) { [] }
12
+
13
+ its(:content) { should eql('(foo)') }
14
+
15
+ it_should_behave_like 'a command method'
16
+ end
17
+
18
+ context 'with first argument' do
19
+ let(:arguments) { ['first '] }
20
+
21
+ its(:content) { should eql('first foo)') }
22
+
23
+ it_should_behave_like 'a command method'
24
+ end
25
+
26
+ context 'with first and second argument' do
27
+ let(:arguments) { ['first ', ' second'] }
28
+
29
+ its(:content) { should eql('first foo second') }
30
+
31
+ it_should_behave_like 'a command method'
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '.wrap_delimited' do
4
+ let(:object) { described_class.new }
5
+
6
+ subject { object.wrap_delimited(open, nodes, close) }
7
+
8
+ let(:open) { '[' }
9
+ let(:close) { ']' }
10
+
11
+ context 'without nodes' do
12
+ let(:nodes) { [] }
13
+
14
+ its(:content) { should eql('[]') }
15
+
16
+ it_should_behave_like 'a command method'
17
+ end
18
+
19
+ class Node
20
+ include Concord.new(:name)
21
+
22
+ def visit(buffer)
23
+ buffer.append(name)
24
+ end
25
+ end
26
+
27
+ context 'with one node' do
28
+ let(:nodes) { [Node.new('A')] }
29
+
30
+ its(:content) { should eql('[A]') }
31
+
32
+ it_should_behave_like 'a command method'
33
+ end
34
+
35
+ context 'with two nodes' do
36
+ let(:nodes) { [Node.new('A'), Node.new('B')] }
37
+
38
+ its(:content) { should eql('[A, B]') }
39
+
40
+ it_should_behave_like 'a command method'
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL, '.literal_node' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.literal_node(value) }
7
+
8
+ let(:value) { mock('Value') }
9
+ let(:result) { mock('Result') }
10
+
11
+ it 'should forward to AQL::Node::Literal.build' do
12
+ AQL::Node::Literal.should_receive(:build).with(value).and_return(result)
13
+ should be(result)
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL, '.name_ndoe' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.name_node(name) }
7
+
8
+ context 'when name is a symbol' do
9
+ let(:name) { :foo }
10
+
11
+ it { should eql(AQL::Node::Name.new('foo')) }
12
+ end
13
+
14
+ context 'when name is a string' do
15
+ let(:name) { 'foo' }
16
+
17
+ it { should eql(AQL::Node::Name.new('foo')) }
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Attribute, '#aql' do
4
+ let(:object) { described_class.new(target, name) }
5
+
6
+ let(:name) { AQL::Node::Name.new(attribute_name) }
7
+ let(:target) { AQL::Node::Name.new(target_name) }
8
+
9
+ context 'with regular names' do
10
+ let(:target_name) { 'foo' }
11
+ let(:attribute_name) { 'bar' }
12
+
13
+ expect_aql('`foo`.`bar`')
14
+ end
15
+
16
+ context 'with keyword names' do
17
+ let(:target_name) { 'sort' }
18
+ let(:attribute_name) { 'filter' }
19
+
20
+ expect_aql('`sort`.`filter`')
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Block, '#aql' do
4
+ let(:object) { described_class.new(elements) }
5
+
6
+ context 'with single element' do
7
+ let(:elements) do
8
+ [AQL::Node::Operation::Unary::Filter.new(AQL::Node::Literal.build(true))]
9
+ end
10
+
11
+ let(:name) { 'foo bar' }
12
+
13
+ expect_aql('FILTER true')
14
+ end
15
+
16
+ context 'with multiple elements' do
17
+ let(:elements) do
18
+ [
19
+ AQL::Node::Operation::Unary::Filter.new(AQL::Node::Literal.build(true)),
20
+ AQL::Node::Operation::Unary::Return.new(AQL::Node::Literal.build(false))
21
+ ]
22
+ end
23
+
24
+ let(:name) { 'foo bar' }
25
+
26
+ expect_aql('FILTER true RETURN false')
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Call, '#aql' do
4
+ let(:object) { described_class.new(name, arguments) }
5
+
6
+ let(:name) { 'FOO' }
7
+
8
+ context 'without arguments' do
9
+ let(:arguments) { [] }
10
+
11
+ expect_aql <<-AQL
12
+ FOO()
13
+ AQL
14
+ end
15
+
16
+ context 'with single argument' do
17
+ let(:arguments) { [AQL::Node::Literal.build(1)] }
18
+
19
+ expect_aql <<-AQL
20
+ FOO(1)
21
+ AQL
22
+ end
23
+
24
+ context 'with multiple arguments' do
25
+ let(:arguments) { [AQL::Node::Literal.build(1), AQL::Node::Literal.build(2)] }
26
+
27
+ expect_aql <<-AQL
28
+ FOO(1, 2)
29
+ AQL
30
+ end
31
+
32
+ context 'with FOR statement as argument' do
33
+ let(:arguments) { [AQL::Node::Operation::For.new(AQL::Node::Name.new('left'), AQL::Node::Name.new('right'), AQL::Node::Name.new('body'))] }
34
+
35
+ expect_aql <<-AQL
36
+ FOO((FOR `left` IN `right` `body`))
37
+ AQL
38
+ end
39
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal, '.build' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.build(input) }
7
+
8
+ context 'string' do
9
+ let(:input) { 'foo' }
10
+ it { should eql(AQL::Node::Literal::Primitive::String.new('foo')) }
11
+ end
12
+
13
+ context 'number' do
14
+
15
+ context 'fixnum' do
16
+ let(:input) { 1 }
17
+ it { should eql(AQL::Node::Literal::Primitive::Number.new(1)) }
18
+ end
19
+
20
+ context 'float' do
21
+ let(:input) { 1.0 }
22
+ it { should eql(AQL::Node::Literal::Primitive::Number.new(1.0)) }
23
+ end
24
+
25
+ end
26
+
27
+ context 'singleton' do
28
+
29
+ context 'nil' do
30
+ let(:input) { nil }
31
+ it { should be(AQL::Node::Literal::Singleton::NULL) }
32
+ end
33
+
34
+ context 'true' do
35
+ let(:input) { true }
36
+ it { should be(AQL::Node::Literal::Singleton::TRUE) }
37
+ end
38
+
39
+ context 'false' do
40
+ let(:input) { false }
41
+ it { should be(AQL::Node::Literal::Singleton::FALSE) }
42
+ end
43
+
44
+ end
45
+
46
+ context 'array' do
47
+
48
+ context 'empty' do
49
+ let(:input) { [] }
50
+ it { should eql(AQL::Node::Literal::Composed::List.new([])) }
51
+ end
52
+
53
+ context 'plain' do
54
+ context 'homogen' do
55
+ let(:input) { [1, 2] }
56
+ it do
57
+ should eql(AQL::Node::Literal::Composed::List.new([
58
+ AQL::Node::Literal::Primitive::Number.new(1),
59
+ AQL::Node::Literal::Primitive::Number.new(2)
60
+ ]))
61
+ end
62
+ end
63
+
64
+ context 'heterogen' do
65
+ let(:input) { [1, false] }
66
+
67
+ specify do
68
+ should eql(AQL::Node::Literal::Composed::List.new([
69
+ AQL::Node::Literal::Primitive::Number.new(1),
70
+ AQL::Node::Literal::Singleton::FALSE
71
+ ]))
72
+ end
73
+ end
74
+ end
75
+
76
+ context 'nested' do
77
+ let(:input) { [[1]] }
78
+
79
+ specify do
80
+ should eql(AQL::Node::Literal::Composed::List.new([
81
+ AQL::Node::Literal::Composed::List.new([
82
+ AQL::Node::Literal::Primitive::Number.new(1)
83
+ ])
84
+ ]))
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'hash' do
90
+
91
+ context 'empty' do
92
+ let(:input) { {} }
93
+
94
+ it { should eql(AQL::Node::Literal::Composed::Document.new([])) }
95
+ end
96
+
97
+ context 'plain' do
98
+ let(:input) { { 1 => 2 } }
99
+
100
+ specify do
101
+ should eql(AQL::Node::Literal::Composed::Document.new([
102
+ AQL::Node::Literal::Composed::Document::Attribute.new(
103
+ AQL::Node::Literal::Primitive::Number.new(1),
104
+ AQL::Node::Literal::Primitive::Number.new(2)
105
+ )
106
+ ]))
107
+ end
108
+ end
109
+
110
+ context 'nested' do
111
+ let(:input) { { 0 => { 1 => 2 } } }
112
+
113
+ specify do
114
+ inner = AQL::Node::Literal::Composed::Document.new([
115
+ AQL::Node::Literal::Composed::Document::Attribute.new(
116
+ AQL::Node::Literal::Primitive::Number.new(1),
117
+ AQL::Node::Literal::Primitive::Number.new(2)
118
+ )
119
+ ])
120
+
121
+ should eql(AQL::Node::Literal::Composed::Document.new([
122
+ AQL::Node::Literal::Composed::Document::Attribute.new(
123
+ AQL::Node::Literal::Primitive::Number.new(0),
124
+ inner
125
+ )
126
+ ]))
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'unhandled' do
132
+ let(:input) { :foo }
133
+
134
+ it 'should raise error' do
135
+ expect { subject }.to raise_error(RuntimeError, 'No support for literal Symbol')
136
+ end
137
+ end
138
+
139
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal, '.construct' do
4
+ let(:class_under_test) do
5
+ Class.new(described_class) do
6
+ include Concord.new(:input)
7
+ end
8
+ end
9
+
10
+ let(:input) { mock('Input') }
11
+ let(:object) { class_under_test }
12
+
13
+ subject { object.construct(input) }
14
+
15
+ it { should eql(class_under_test.new(input)) }
16
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal, '#handle' do
4
+ Dummy = Class.new do
5
+ include Equalizer.new
6
+ end
7
+
8
+ let(:object) { described_class }
9
+
10
+ subject { object.build(Dummy.new) }
11
+
12
+ let(:input) { Dummy.new }
13
+
14
+ let(:class_under_test) do
15
+ Class.new(described_class) do
16
+ include Concord.new(:object)
17
+ handle(Dummy)
18
+ end
19
+ end
20
+
21
+ it { should eql(class_under_test.new(input)) }
22
+ end