aql 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,75 @@
1
+ module AQL
2
+ class Node
3
+ class Operation
4
+ # Base class for unary operations
5
+ class Unary < self
6
+ include Concord.new(:expression)
7
+
8
+ private
9
+
10
+ # Emit node
11
+ #
12
+ # @param [Buffer] buffer
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def emit(buffer)
19
+ buffer.append("#{keyword} ")
20
+ expression.visit(buffer)
21
+ end
22
+
23
+ # Return keyword
24
+ #
25
+ # @return [Symbol]
26
+ #
27
+ # @api private
28
+ #
29
+ def keyword
30
+ self.class::KEYWORD
31
+ end
32
+
33
+ # Filter operation
34
+ class Filter < self
35
+ KEYWORD = :FILTER
36
+ end
37
+
38
+ # Return operation
39
+ class Return < self
40
+ KEYWORD = :RETURN
41
+ end
42
+
43
+ # Abstract base class for sort orders
44
+ class Direction < self
45
+
46
+ private
47
+
48
+ # Emit node
49
+ #
50
+ # @param [Buffer] buffer
51
+ #
52
+ # @return [undefined]
53
+ #
54
+ # @api private
55
+ #
56
+ def emit(buffer)
57
+ expression.visit(buffer)
58
+ buffer.append(" #{keyword}")
59
+ end
60
+
61
+ # Asecnding sort direction
62
+ class Ascending < self
63
+ KEYWORD = :ASC
64
+ end
65
+
66
+ # Descending sort direction
67
+ class Descending < self
68
+ KEYWORD = :DESC
69
+ end
70
+
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,20 @@
1
+ module AQL
2
+ class Node
3
+ # Base class for operators
4
+ class Operator < self
5
+
6
+ private
7
+
8
+ # Return operator symbol
9
+ #
10
+ # @return [Symbol]
11
+ #
12
+ # @api private
13
+ #
14
+ def operator
15
+ self.class::SYMBOL
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ module AQL
2
+ class Node
3
+ class Operator
4
+ # Assignment operator
5
+ class Assignment < self
6
+ include Concord.new(:name, :value)
7
+ SYMBOL = :'='
8
+
9
+ private
10
+
11
+ # Emit into buffer
12
+ #
13
+ # @param [Buffer] buffer
14
+ #
15
+ # @return [undefined]
16
+ #
17
+ # @api private
18
+ #
19
+ def emit(buffer)
20
+ name.visit(buffer)
21
+ buffer.append(" #{SYMBOL} ")
22
+ value.visit(buffer)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,92 @@
1
+ module AQL
2
+ class Node
3
+ class Operator
4
+ # Base class for binary operators
5
+ class Binary < self
6
+ include Concord.new(:left, :right)
7
+
8
+ private
9
+
10
+ # Emit node
11
+ #
12
+ # @return [undefined]
13
+ #
14
+ # @api private
15
+ #
16
+ def emit(buffer)
17
+ buffer.binary(left, operator, right)
18
+ end
19
+
20
+ # Binary equality operator
21
+ class Equality < self
22
+ SYMBOL = :==
23
+ end
24
+
25
+ # Binary inequality operator
26
+ class Inequality < self
27
+ SYMBOL = :'!='
28
+ end
29
+
30
+ # Binary or operator
31
+ class Or < self
32
+ SYMBOL = :'||'
33
+ end
34
+
35
+ # Binary and operator
36
+ class And < self
37
+ SYMBOL = :'&&'
38
+ end
39
+
40
+ # Binary in operator
41
+ class In < self
42
+ SYMBOL = :'IN'
43
+ end
44
+
45
+ # Binary less than operator
46
+ class LessThan < self
47
+ SYMBOL = :'<'
48
+ end
49
+
50
+ # Binary less than or equal to operator
51
+ class LessThanOrEqualTo < self
52
+ SYMBOL = :'<='
53
+ end
54
+
55
+ # Binary greater than operator
56
+ class GreaterThan < self
57
+ SYMBOL = :'>'
58
+ end
59
+
60
+ # Binary greater than or equal to operator
61
+ class GreaterThanOrEqualTo < self
62
+ SYMBOL = :'>='
63
+ end
64
+
65
+ # Binary addition operator
66
+ class Addition < self
67
+ SYMBOL = :+
68
+ end
69
+
70
+ # Binary subtraction operator
71
+ class Subtraction < self
72
+ SYMBOL = :-
73
+ end
74
+
75
+ # Binary multiplication operator
76
+ class Multiplication < self
77
+ SYMBOL = :*
78
+ end
79
+
80
+ # Binary division operator
81
+ class Division < self
82
+ SYMBOL = :/
83
+ end
84
+
85
+ # Binary modulo operator
86
+ class Modulo < self
87
+ SYMBOL = :%
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,48 @@
1
+ module AQL
2
+ class Node
3
+ class Operator
4
+ # Base class for n-ary operators
5
+ class Nary < self
6
+ include Concord.new(:body)
7
+
8
+ private
9
+
10
+ # Emit node
11
+ #
12
+ # @return [undefined]
13
+ #
14
+ # @api private
15
+ #
16
+ def emit(buffer)
17
+ local = body
18
+ if local.length == 1
19
+ local.first.visit(buffer)
20
+ return
21
+ end
22
+ emit_body(buffer)
23
+ end
24
+
25
+ # Emit body
26
+ #
27
+ # @rteturn [undefined]
28
+ #
29
+ # @api private
30
+ #
31
+ def emit_body(buffer)
32
+ buffer.parentheses do
33
+ buffer.delimited(body, " #{self.class::SYMBOL} ")
34
+ end
35
+ end
36
+
37
+ # Nary and operator
38
+ #
39
+ # Only present to ease generation of join filters.
40
+ #
41
+ class And < self
42
+ SYMBOL = :'&&'
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ module AQL
2
+ class Node
3
+ class Operator
4
+ # Ternary operator
5
+ class Ternary < self
6
+ include Concord.new(:condition, :left, :right)
7
+
8
+ SYMBOL = :'?'
9
+
10
+ private
11
+
12
+ # Emit node
13
+ #
14
+ # @param [Buffer] buffer
15
+ #
16
+ # @return [undefined]
17
+ #
18
+ # @api private
19
+ #
20
+ def emit(buffer)
21
+ condition.visit(buffer)
22
+ buffer.append(" #{operator} ")
23
+ left.visit(buffer)
24
+ buffer.append(' : ')
25
+ right.visit(buffer)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ module AQL
2
+ class Node
3
+ class Operator
4
+ # Base class for unary operators
5
+ class Unary < self
6
+ include Concord.new(:target)
7
+
8
+ private
9
+
10
+ # Emit node
11
+ #
12
+ # @return [undefined]
13
+ #
14
+ # @api private
15
+ #
16
+ def emit(buffer)
17
+ buffer.append(operator)
18
+ target.visit(buffer)
19
+ end
20
+
21
+ # Unary negation operator
22
+ class Negation < self
23
+ SYMBOL = :'!'
24
+ end
25
+
26
+ # Unary plus operator
27
+ class Plus < self
28
+ SYMBOL = :+
29
+ end
30
+
31
+ # Unary minus operator
32
+ class Minus < self
33
+ SYMBOL = :-
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ shared_examples_for 'Node#aql' do
2
+ subject { object.aql }
3
+
4
+ it { should eql(expected_aql) }
5
+ its(:frozen?) { should be(true) }
6
+ it_should_behave_like 'an idempotent method'
7
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'devtools'
4
+ require 'aql'
5
+ require 'rspec'
6
+
7
+ Devtools.init_spec_helper
8
+
9
+ RSpec.configure do |config|
10
+ config.extend(AQLHelper)
11
+ end
@@ -0,0 +1,12 @@
1
+ module AQLHelper
2
+ def compress_aql(string)
3
+ string.gsub(/^[ ]*/, '').split("\n").join(' ')
4
+ end
5
+
6
+ def expect_aql(string)
7
+ expected_aql = compress_aql(string)
8
+ subject { object.aql }
9
+ it_should_behave_like 'an idempotent method'
10
+ it { should eql(expected_aql) }
11
+ end
12
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '#append' do
4
+ unless defined?(Encoding)
5
+ before do
6
+ pending "No support for encodings under #{Devtools.rvm}"
7
+ end
8
+ end
9
+
10
+ let(:object) { described_class.new }
11
+ subject { object.append(content) }
12
+ let(:utf8) { Encoding::UTF_8 }
13
+
14
+ this_spec = 'AQL::Bufffer#append'
15
+
16
+ shared_examples_for this_spec do
17
+ it 'should append content to buffer' do
18
+ expect { subject }.to change { object.content }.from('').to(expected_content)
19
+ end
20
+
21
+ it 'should return utf-8 encoded content' do
22
+ subject.content.encoding.should be(utf8)
23
+ end
24
+
25
+ it_should_behave_like 'a command method'
26
+ end
27
+
28
+ context 'ascii encoded content' do
29
+ let(:content) { 'foo' }
30
+ let(:expected_content) { 'foo'.encode('utf-8') }
31
+
32
+ it_should_behave_like this_spec
33
+ end
34
+
35
+ context 'utf-8 encoded content' do
36
+ let(:content) { "\xC3\xBC".force_encoding(utf8) }
37
+ let(:expected_content) { content.dup }
38
+
39
+ it_should_behave_like this_spec
40
+ end
41
+
42
+ context 'with non utf-8 encodable content' do
43
+ let(:content) { "\xC3\x28".force_encoding('binary') }
44
+
45
+ let(:expected_message) do
46
+ case Devtools.rvm_name
47
+ when 'rbx'
48
+ '"\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8'
49
+ else
50
+ '"\xC3" from ASCII-8BIT to UTF-8'
51
+ end
52
+ end
53
+
54
+ it 'should raise error' do
55
+ expect { subject }.to raise_error(Encoding::UndefinedConversionError, expected_message)
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Buffer, '#binary' do
4
+ subject { object.binary(left, operator, right) }
5
+
6
+ let(:object) { described_class.new }
7
+ let(:left) { Node.new('left') }
8
+ let(:right) { Node.new('right') }
9
+ let(:operator) { :operator }
10
+
11
+ class Node
12
+ include Concord.new(:name)
13
+
14
+ def visit(buffer)
15
+ buffer.append(name)
16
+ end
17
+ end
18
+
19
+ its(:content) { should eql('(left operator right)') }
20
+
21
+ it_should_behave_like 'a command method'
22
+ end