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,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Composed::Document, '#aql' do
4
+ let(:object) { AQL::Node::Literal.build(input) }
5
+
6
+ if RUBY_VERSION < '1.9'
7
+ before do
8
+ pending 'Test for ordered hashes, ruby 1.8 has unordered ones'
9
+ end
10
+ end
11
+
12
+ examples = {
13
+ {} => '{}',
14
+ { 'name' => 'Peter' } => '{"name": "Peter"}',
15
+ {
16
+ 'name' => 'John',
17
+ 'likes' => %w(Swimming Skiing),
18
+ 'address' => {
19
+ 'street' => 'Cucumber lane',
20
+ 'zip' => '94242'
21
+ }
22
+ } => '{"name": "John", "likes": ["Swimming", "Skiing"], "address": {"street": "Cucumber lane", "zip": "94242"}}'
23
+ }
24
+
25
+ examples.each do |input, expectation|
26
+ context "with #{input.inspect} as input" do
27
+ let(:input) { input }
28
+
29
+ expect_aql(expectation)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Composed::Document::Attribute, '#aql' do
4
+ class Node
5
+ include Concord.new(:token)
6
+
7
+ def visit(buffer)
8
+ buffer.append(token)
9
+ end
10
+ end
11
+
12
+ let(:object) { described_class.new(Node.new('foo'), Node.new('bar')) }
13
+
14
+ expect_aql('foo: bar')
15
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Composed::Document, '.construct' do
4
+ let(:object) { described_class }
5
+ let(:subject) { object.construct(input) }
6
+
7
+ context 'without attributes' do
8
+ let(:input) { {} }
9
+
10
+ it { should eql(described_class.new([])) }
11
+ end
12
+
13
+ context 'with attributes' do
14
+ let(:input) { { 1 => 2 } }
15
+
16
+ let(:attribute) do
17
+ AQL::Node::Literal::Composed::Document::Attribute.new(
18
+ AQL::Node::Literal.build(1), AQL::Node::Literal.build(2)
19
+ )
20
+ end
21
+
22
+ it { should eql(described_class.new([attribute])) }
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Composed::List, '#aql' do
4
+ let(:object) { AQL::Node::Literal.build(input) }
5
+
6
+ examples = {
7
+ [] => '[]',
8
+ [1, 2, 3] => '[1, 2, 3]',
9
+ [-99, "yikes!", [ true, [ "no"], []], 1 ] => '[-99, "yikes!", [true, ["no"], []], 1]',
10
+ [["fox", "marshal"]] => '[["fox", "marshal"]]',
11
+ [nil] => '[null]'
12
+ }
13
+
14
+ examples.each do |input, expectation|
15
+ context "with #{input.inspect} as input" do
16
+ let(:input) { input }
17
+ expect_aql(expectation)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Composed::List, '.constant' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.construct(input) }
7
+
8
+ context 'with empty input' do
9
+ let(:input) { [] }
10
+
11
+ it { should eql(described_class.new([])) }
12
+ end
13
+
14
+ context 'with scalar values as input' do
15
+ let(:input) { [1, 2] }
16
+
17
+ it 'should return correct ast' do
18
+ should eql(described_class.new([
19
+ AQL::Node::Literal::Primitive::Number.new(1),
20
+ AQL::Node::Literal::Primitive::Number.new(2)
21
+ ]))
22
+ end
23
+
24
+ end
25
+
26
+ context 'with nested scalar values as input' do
27
+ let(:input) { [1, [2] ] }
28
+
29
+ it 'should return correct ast' do
30
+ should eql(described_class.new([
31
+ AQL::Node::Literal::Primitive::Number.new(1),
32
+ AQL::Node::Literal::Composed::List.construct([2])
33
+ ]))
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Primitive::Number, '#aql' do
4
+ let(:object) { described_class.new(number) }
5
+
6
+ examples = {
7
+ 1 => '1',
8
+ 42 => '42',
9
+ -1 => '-1',
10
+ -42 => '-42',
11
+ 1.23 => '1.23',
12
+ -99.99 => '-99.99',
13
+ 0.1 => '0.1',
14
+ -4.87e103 => '-4.87e+103'
15
+ }
16
+
17
+ examples.each do |number, expectation|
18
+ context "with #{number.inspect} as input" do
19
+ let(:number) { number }
20
+ expect_aql(expectation)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Primitive::String, '#aql' do
4
+ let(:object) { described_class.new(string) }
5
+
6
+ examples = {
7
+ '' => '""',
8
+ 'yikes!' => '"yikes!"',
9
+ 'this is a "quoted" word' => '"this is a \"quoted\" word"',
10
+ 'this is a longer string.' => '"this is a longer string."',
11
+ 'the path separator on Windows is \\' => '"the path separator on Windows is \\\\"',
12
+ "some newlines \n" => '"some newlines \n"'
13
+ }
14
+
15
+ examples.each do |string, expectation|
16
+ context "with #{string.inspect} as input" do
17
+ let(:string) { string }
18
+ expect_aql(expectation)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Singleton do
4
+
5
+ let(:class_under_test) do
6
+ Class.new(described_class) do
7
+ public_class_method :new
8
+ end
9
+ end
10
+
11
+ let(:object) { class_under_test.new('content') }
12
+
13
+ expect_aql('content')
14
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Literal::Singleton, '.construct' do
4
+ let(:object) { described_class }
5
+ subject { object.construct(input) }
6
+
7
+ context 'with false as input' do
8
+ let(:input) { false }
9
+ it { should be(AQL::Node::Literal::Singleton::FALSE) }
10
+ end
11
+
12
+ context 'with true as input' do
13
+ let(:input) { true }
14
+ it { should be(AQL::Node::Literal::Singleton::TRUE) }
15
+ end
16
+
17
+ context 'with nil as input' do
18
+ let(:input) { nil }
19
+ it { should be(AQL::Node::Literal::Singleton::NULL) }
20
+ end
21
+
22
+ context 'with anything else' do
23
+ let(:input) { :foo }
24
+
25
+ it 'should raise error' do
26
+ expected = RUBY_VERSION < '1.9' ? IndexError : KeyError
27
+ expect { subject }.to raise_error(expected)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Name, '#aql' do
4
+ let(:object) { described_class.new(name) }
5
+
6
+ context 'with non keyword name' do
7
+ context 'not containing whitespace' do
8
+ let(:name) { 'foo' }
9
+ expect_aql('`foo`')
10
+ end
11
+
12
+ context 'not containing' do
13
+ let(:name) { 'foo bar' }
14
+ expect_aql('`foo bar`')
15
+ end
16
+ end
17
+
18
+ context 'with keyword name' do
19
+ AQL::KEYWORDS.each do |keyword|
20
+ context keyword do
21
+ context 'uppercase' do
22
+ let(:name) { keyword }
23
+ expect_aql(%Q(`#{keyword}`))
24
+ end
25
+
26
+ context 'lowercased' do
27
+ let(:name) { keyword.downcase }
28
+ expect_aql(%Q(`#{keyword.downcase}`))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::NULL, '#aql' do
4
+ let(:object) { described_class }
5
+
6
+ expect_aql('')
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Binary::Let, '#aql' do
4
+
5
+ let(:left) { AQL::Node::Name.new('foo') }
6
+ let(:right) { AQL::Node::Literal.build('bar') }
7
+ let(:object) { described_class.new(left, right) }
8
+
9
+ expect_aql('LET `foo` = "bar"')
10
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::For, '#aql' do
4
+ let(:left) { AQL::Node::Name.new('left') }
5
+ let(:body) { AQL::Node::Name.new('body') }
6
+
7
+ let(:object) { described_class.new(left, right, body) }
8
+
9
+ context 'when right is a name' do
10
+ let(:right) { AQL::Node::Name.new('right') }
11
+ expect_aql('FOR `left` IN `right` `body`')
12
+ end
13
+
14
+ context 'when right is anything else' do
15
+ let(:right) { AQL::Node::Literal.build([1, 2, 3]) }
16
+ expect_aql('FOR `left` IN ([1, 2, 3]) `body`')
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation, '#keyword' do
4
+ let(:class_under_test) do
5
+ Class.new(described_class) do
6
+ const_set(:KEYWORD, 'KEYWORD')
7
+ public :keyword
8
+ end
9
+ end
10
+
11
+ subject { object.keyword }
12
+
13
+ let(:object) { class_under_test.new }
14
+
15
+ it { should eql('KEYWORD') }
16
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Limit, '#aql' do
4
+ let(:object) { described_class.new(count, offset) }
5
+
6
+ context 'without offset' do
7
+ let(:count) { AQL::Node::Literal.build(10) }
8
+ let(:offset) { nil }
9
+
10
+ expect_aql('LIMIT 10')
11
+ end
12
+
13
+ context 'with offset' do
14
+ let(:count) { AQL::Node::Literal.build(10) }
15
+ let(:offset) { AQL::Node::Literal.build(5) }
16
+
17
+ expect_aql('LIMIT 5, 10')
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Nary, '#aql' do
4
+ let(:class_under_test) do
5
+ Class.new(described_class) do
6
+ const_set(:KEYWORD, 'KEYWORD')
7
+ end
8
+ end
9
+
10
+ let(:foo) { AQL::Node::Name.new('foo') }
11
+ let(:bar) { AQL::Node::Name.new('bar') }
12
+
13
+ let(:object) { class_under_test.new([foo, bar]) }
14
+
15
+ expect_aql('KEYWORD `foo`, `bar`')
16
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Nary::Collect::Into, '#aql' do
4
+
5
+ let(:object) { described_class.new(body, name) }
6
+
7
+ let(:body) { [AQL.name_node('foo'), AQL.name_node('bar')] }
8
+ let(:name) { AQL.name_node('baz') }
9
+
10
+ expect_aql('COLLECT `foo`, `bar` INTO `baz`')
11
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Nary::Sort, '#aql' do
4
+
5
+ let(:object) { described_class.new(directions) }
6
+
7
+ let(:foo) { AQL::Node::Name.new('foo') }
8
+ let(:bar) { AQL::Node::Name.new('bar') }
9
+
10
+ let(:direction_a) { AQL::Node::Operation::Unary::Direction::Ascending.new(foo) }
11
+ let(:direction_b) { AQL::Node::Operation::Unary::Direction::Descending.new(bar) }
12
+
13
+ context 'one direction' do
14
+ let(:directions) { [direction_a] }
15
+ expect_aql('SORT `foo` ASC')
16
+ end
17
+
18
+ context 'two directions' do
19
+ let(:directions) { [direction_a, direction_b] }
20
+ expect_aql('SORT `foo` ASC, `bar` DESC')
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Unary, '#aql' do
4
+ let(:class_under_test) do
5
+ Class.new(described_class) do
6
+ const_set('KEYWORD', 'KEYWORD')
7
+ end
8
+ end
9
+
10
+ let(:object) { class_under_test.new(AQL::Node::Literal.build(1)) }
11
+ expect_aql('KEYWORD 1')
12
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Unary::Direction, '#aql' do
4
+ let(:class_under_test) do
5
+ Class.new(described_class) do
6
+ const_set(:KEYWORD, 'KEYWORD')
7
+ end
8
+ end
9
+
10
+ let(:foo) { AQL::Node::Name.new('foo') }
11
+ let(:object) { class_under_test.new(foo) }
12
+
13
+ expect_aql('`foo` KEYWORD')
14
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe AQL::Node::Operation::Unary::Filter, '#aql' do
4
+ let(:object) { described_class.new(expression) }
5
+
6
+ context 'with constant binary expression' do
7
+ let(:expression) { AQL::Node::Literal.build(true) }
8
+
9
+ expect_aql('FILTER true')
10
+ end
11
+
12
+ context 'with binary expression' do
13
+ let(:expression) do
14
+ foo = AQL::Node::Name.new('foo')
15
+ AQL::Node::Operator::Binary::LessThan.new(foo, AQL::Node::Literal.build(9))
16
+ end
17
+
18
+ expect_aql('FILTER (`foo` < 9)')
19
+ end
20
+ end