CloudSesame 0.1.6 → 0.2.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/cloud_sesame.gemspec +1 -1
- data/lib/cloud_sesame/domain/base.rb +9 -0
- data/lib/cloud_sesame/query/ast/and.rb +1 -1
- data/lib/cloud_sesame/query/ast/block_chaining_relation.rb +30 -0
- data/lib/cloud_sesame/query/ast/field_array.rb +31 -0
- data/lib/cloud_sesame/query/ast/literal.rb +15 -9
- data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +26 -8
- data/lib/cloud_sesame/query/ast/near.rb +5 -10
- data/lib/cloud_sesame/query/ast/not.rb +11 -1
- data/lib/cloud_sesame/query/ast/operator.rb +26 -0
- data/lib/cloud_sesame/query/ast/or.rb +1 -1
- data/lib/cloud_sesame/query/ast/phrase.rb +2 -6
- data/lib/cloud_sesame/query/ast/prefix.rb +2 -6
- data/lib/cloud_sesame/query/ast/range_value.rb +1 -1
- data/lib/cloud_sesame/query/ast/root.rb +7 -3
- data/lib/cloud_sesame/query/ast/single_expression_operator.rb +16 -7
- data/lib/cloud_sesame/query/ast/term.rb +2 -6
- data/lib/cloud_sesame/query/ast/value.rb +5 -5
- data/lib/cloud_sesame/query/builder.rb +18 -8
- data/lib/cloud_sesame/query/dsl/base.rb +6 -6
- data/lib/cloud_sesame/query/dsl/block_chaining_methods.rb +26 -0
- data/lib/cloud_sesame/query/dsl/block_methods.rb +41 -0
- data/lib/cloud_sesame/query/dsl/field_array_methods.rb +70 -0
- data/lib/cloud_sesame/query/dsl/field_methods.rb +25 -0
- data/lib/cloud_sesame/query/dsl/{filter_query.rb → filter_query_methods.rb} +3 -9
- data/lib/cloud_sesame/query/dsl/operator_methods.rb +53 -0
- data/lib/cloud_sesame/query/dsl/{page.rb → page_methods.rb} +12 -1
- data/lib/cloud_sesame/query/dsl/{query.rb → query_methods.rb} +1 -1
- data/lib/cloud_sesame/query/dsl/{return.rb → return_methods.rb} +1 -1
- data/lib/cloud_sesame/query/dsl/{scope.rb → scope_methods.rb} +3 -3
- data/lib/cloud_sesame/query/dsl/{sort.rb → sort_methods.rb} +1 -1
- data/lib/cloud_sesame/query/dsl/{value.rb → value_methods.rb} +1 -4
- data/lib/cloud_sesame/query/{ast/leaf.rb → error/invalid_syntax.rb} +2 -2
- data/lib/cloud_sesame/query/fuzziness.rb +54 -0
- data/lib/cloud_sesame/query/node/page.rb +6 -6
- data/lib/cloud_sesame/query/node/query.rb +14 -10
- data/lib/cloud_sesame/query/node/sort.rb +1 -1
- data/lib/cloud_sesame.rb +19 -16
- data/spec/cloud_sesame/query/dsl/base_spec.rb +2 -2
- data/spec/cloud_sesame/query/dsl/block_chaining_methods_spec.rb +73 -0
- data/spec/cloud_sesame/query/dsl/block_methods_spec.rb +117 -0
- data/spec/cloud_sesame/query/dsl/field_array_methods_spec.rb +69 -0
- data/spec/cloud_sesame/query/dsl/field_methods_spec.rb +54 -0
- data/spec/cloud_sesame/query/node/query_spec.rb +16 -9
- data/spec/cloud_sesame_spec.rb +79 -68
- metadata +26 -34
- data/lib/cloud_sesame/query/ast/compound_array.rb +0 -77
- data/lib/cloud_sesame/query/ast/multi_branch.rb +0 -27
- data/lib/cloud_sesame/query/ast/single_branch.rb +0 -27
- data/lib/cloud_sesame/query/dsl/and.rb +0 -19
- data/lib/cloud_sesame/query/dsl/boost.rb +0 -20
- data/lib/cloud_sesame/query/dsl/literal.rb +0 -72
- data/lib/cloud_sesame/query/dsl/or.rb +0 -19
- data/spec/cloud_sesame/query/ast/and_spec.rb +0 -13
- data/spec/cloud_sesame/query/ast/literal_spec.rb +0 -37
- data/spec/cloud_sesame/query/ast/multi_branch_spec.rb +0 -65
- data/spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb +0 -26
- data/spec/cloud_sesame/query/ast/or_spec.rb +0 -13
- data/spec/cloud_sesame/query/ast/root_spec.rb +0 -43
- data/spec/cloud_sesame/query/ast/value_spec.rb +0 -40
- data/spec/cloud_sesame/query/dsl/filter_query_spec.rb +0 -108
- data/spec/cloud_sesame/query/node/request_spec.rb +0 -71
@@ -1,37 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module CloudSesame
|
4
|
-
module Query
|
5
|
-
module AST
|
6
|
-
describe Literal do
|
7
|
-
let(:literal) { Literal.new('description', 'Shoes') }
|
8
|
-
let(:value) { Value.new("Shoes") }
|
9
|
-
|
10
|
-
# before { allow(Value).to receive(:new).and_return(value) }
|
11
|
-
|
12
|
-
describe '#initialize' do
|
13
|
-
it 'should store field' do
|
14
|
-
expect(literal.field).to eq('description')
|
15
|
-
end
|
16
|
-
it 'should create value node and store it' do
|
17
|
-
expect(Value).to receive(:new).with('Shoes').and_return(value)
|
18
|
-
expect(literal.value).to be_kind_of Value
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#compile' do
|
23
|
-
context 'when options is empty' do
|
24
|
-
it 'should compile value' do
|
25
|
-
expect_any_instance_of(Value).to receive(:compile).and_return("'Shoes'")
|
26
|
-
literal.compile
|
27
|
-
end
|
28
|
-
it 'should join the field and compiled value with colon' do
|
29
|
-
expect(literal.compile).to eq("description:'Shoes'")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module CloudSesame
|
4
|
-
module Query
|
5
|
-
module AST
|
6
|
-
describe MultiBranch do
|
7
|
-
let(:context) { {} }
|
8
|
-
let(:proc) { Proc.new { } }
|
9
|
-
let(:node) { MultiBranch.new(context, &proc) }
|
10
|
-
|
11
|
-
describe '#initialize' do
|
12
|
-
it 'should store the context' do
|
13
|
-
expect(node.context).to eq context
|
14
|
-
end
|
15
|
-
it 'should accepts an block and eval it' do
|
16
|
-
proc = Proc.new { test }
|
17
|
-
expect_any_instance_of(MultiBranch).to receive(:test)
|
18
|
-
MultiBranch.new(context, &proc)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#children' do
|
23
|
-
it 'should instantiate an empty array' do
|
24
|
-
expect(CompoundArray).to receive(:new).and_call_original
|
25
|
-
node.children
|
26
|
-
end
|
27
|
-
it 'should return the array' do
|
28
|
-
node.children.concat([1,2,3])
|
29
|
-
expect(node.children).to eq [1,2,3]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '#compile_children' do
|
34
|
-
let(:children) {
|
35
|
-
[Value.new('value1'),
|
36
|
-
Value.new('value2')]
|
37
|
-
}
|
38
|
-
it 'should compile its children' do
|
39
|
-
children.each do |child|
|
40
|
-
expect(child).to receive(:compile)
|
41
|
-
end
|
42
|
-
|
43
|
-
node.children.concat(children)
|
44
|
-
node.compile_children
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'should join its compiled children with a space' do
|
48
|
-
children.each do |child|
|
49
|
-
expect(child).to receive(:compile).and_call_original
|
50
|
-
end
|
51
|
-
node.children.concat(children)
|
52
|
-
expect(node.compile_children).to eq("'value1' 'value2'")
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe 'Query DSL' do
|
57
|
-
it 'should be included' do
|
58
|
-
expect(node).to respond_to(:and, :or)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module CloudSesame
|
4
|
-
module Query
|
5
|
-
module AST
|
6
|
-
describe MultiExpressionOperator do
|
7
|
-
let(:proc) { Proc.new {} }
|
8
|
-
let(:operator) { MultiExpressionOperator.new({}, &proc )}
|
9
|
-
before { MultiExpressionOperator.symbol = :symbol }
|
10
|
-
|
11
|
-
describe '#compile' do
|
12
|
-
|
13
|
-
it 'should return nil if children are empty' do
|
14
|
-
expect(operator.compile).to eq(nil)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should return a string with the symbol and compile children' do
|
18
|
-
operator.children.push Literal.new(:price, 10)
|
19
|
-
expect(operator.compile).to eq("(symbol price:10)")
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module CloudSesame
|
4
|
-
module Query
|
5
|
-
module AST
|
6
|
-
describe Root do
|
7
|
-
|
8
|
-
let(:root) { Root.new({}) }
|
9
|
-
|
10
|
-
describe '#compile' do
|
11
|
-
before { root.children.concat(children) }
|
12
|
-
|
13
|
-
context 'when it has multiple children' do
|
14
|
-
let(:children) {
|
15
|
-
[Literal.new(:tags, "flash_deal"),
|
16
|
-
Literal.new(:tags, "sales")]
|
17
|
-
}
|
18
|
-
it 'should inject an default operator' do
|
19
|
-
expect(root.compile).to eq "(and tags:'flash_deal' tags:'sales')"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
context 'when it has 1 child' do
|
23
|
-
let(:children) {
|
24
|
-
[Literal.new(:tags, "flash_deal")]
|
25
|
-
}
|
26
|
-
it 'should compile the child' do
|
27
|
-
expect(root).to receive(:compile_children)
|
28
|
-
root.compile
|
29
|
-
end
|
30
|
-
end
|
31
|
-
context 'when it has no children' do
|
32
|
-
let(:children) { [] }
|
33
|
-
it 'should compile the child' do
|
34
|
-
expect(root).to receive(:compile_children)
|
35
|
-
root.compile
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module CloudSesame
|
4
|
-
module Query
|
5
|
-
module AST
|
6
|
-
describe Value do
|
7
|
-
|
8
|
-
let(:value) { Value.new("Shoes") }
|
9
|
-
|
10
|
-
describe '#initialize' do
|
11
|
-
it 'should store the value' do
|
12
|
-
expect(value.data).to eq("Shoes")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#compile' do
|
17
|
-
shared_examples 'return raw data' do
|
18
|
-
it 'should just return the data' do
|
19
|
-
expect(value.compile).to eq value.data
|
20
|
-
end
|
21
|
-
end
|
22
|
-
context 'when data is a string' do
|
23
|
-
it 'should escape the string' do
|
24
|
-
expect(value.compile).to eq "'#{value.data}'"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
context 'when data is a range' do
|
28
|
-
let(:value) { Value.new('[100,}') }
|
29
|
-
include_examples 'return raw data'
|
30
|
-
end
|
31
|
-
context 'when data is a digit' do
|
32
|
-
let(:value) { Value.new(100) }
|
33
|
-
include_examples 'return raw data'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
module CloudSesame
|
2
|
-
module Query
|
3
|
-
module DSL
|
4
|
-
describe FilterQuery do
|
5
|
-
|
6
|
-
class TestClass
|
7
|
-
include Base
|
8
|
-
include FilterQuery
|
9
|
-
def initialize
|
10
|
-
end
|
11
|
-
def children
|
12
|
-
@children ||= AST::CompoundArray.new.scope_to self
|
13
|
-
end
|
14
|
-
def context
|
15
|
-
@context ||= {}
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
subject { TestClass.new }
|
20
|
-
|
21
|
-
describe '#and' do
|
22
|
-
it 'should create an AND node' do
|
23
|
-
expect(AST::And).to receive(:new).with({})
|
24
|
-
subject.and
|
25
|
-
end
|
26
|
-
it 'should add the AND node to it\s children' do
|
27
|
-
expect(AST::And).to receive(:new).with({})
|
28
|
-
expect{ subject.and }.to change{ subject.children.size }.by(1)
|
29
|
-
end
|
30
|
-
it 'should return it\'s own scope' do
|
31
|
-
expect(subject.and).to eq subject
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe '#or' do
|
36
|
-
it 'should create an OR node' do
|
37
|
-
expect(AST::Or).to receive(:new).with({})
|
38
|
-
subject.or
|
39
|
-
end
|
40
|
-
it 'should add the OR node to it\s children' do
|
41
|
-
expect(AST::Or).to receive(:new).with({})
|
42
|
-
expect{ subject.or }.to change{ subject.children.size }.by(1)
|
43
|
-
end
|
44
|
-
it 'should return it\'s own scope' do
|
45
|
-
expect(subject.and).to eq subject
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'included?' do
|
50
|
-
before { subject.context[:fields] = { tags: {}, description: {} } }
|
51
|
-
context 'when there is a field and no value' do
|
52
|
-
it 'should return true if the request contains the field in the filter query' do
|
53
|
-
subject.and { tags 'women' }
|
54
|
-
expect(subject.included?(:tags)).to be_truthy
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'should return false if the request does not contain the field in the filter query' do
|
58
|
-
subject.and { tags.not 'women' }
|
59
|
-
expect(subject.included?(:tags)).to be_falsey
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
context 'when there is a field and a value' do
|
64
|
-
it 'should return true if the request contains the field and the value in the filter query' do
|
65
|
-
subject.and { tags("women") }
|
66
|
-
expect(subject.included?(:tags, "women")).to be_truthy
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'should return false if the request does not contain the field or the value in the filter query' do
|
70
|
-
subject.and{tags('women')}
|
71
|
-
expect(subject.included?(:tags, 'men')).to be_falsey
|
72
|
-
expect(subject.included?(:description, 'women')).to be_falsey
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe 'excluded?' do
|
78
|
-
before { subject.context[:fields] = { tags: {}, description: {} } }
|
79
|
-
context 'when there is a field and no value' do
|
80
|
-
it 'should return true if the request excludes the field in the filter query' do
|
81
|
-
subject.and { tags 'women' }
|
82
|
-
expect(subject.excluded?(:tags)).to be_falsey
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should return false if the request does not exclude the field in the filter query' do
|
86
|
-
subject.and{tags.not('women')}
|
87
|
-
expect(subject.excluded?(:tags)).to be_truthy
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context 'when there is a field and a value' do
|
92
|
-
it 'should return true if the request excludes the field and the value in the filter query' do
|
93
|
-
subject.and{tags.not('women')}
|
94
|
-
expect(subject.excluded?(:tags, 'women')).to be_truthy
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should return false if the request does not exclude the field or the value in the filter query' do
|
98
|
-
subject.and{tags('women')}
|
99
|
-
expect(subject.excluded?(:tags, 'men')).to be_falsey
|
100
|
-
expect(subject.excluded?(:tags, 'women')).to be_falsey
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module CloudSesame
|
4
|
-
module Query
|
5
|
-
module Node
|
6
|
-
describe Request do
|
7
|
-
let(:context) { Domain::Context.new(filter_query: { fields: { tags: {} } }) }
|
8
|
-
let(:request) { Request.new(context) }
|
9
|
-
|
10
|
-
describe '#compile' do
|
11
|
-
context 'when request is empty' do
|
12
|
-
it 'should return an default request' do
|
13
|
-
expect(request.compile).to include(
|
14
|
-
query: "",
|
15
|
-
query_parser: "simple",
|
16
|
-
start: 0,
|
17
|
-
size: 10
|
18
|
-
)
|
19
|
-
expect(request.compile).to_not include(:query_options, :filter_query, :sort)
|
20
|
-
end
|
21
|
-
it 'should set query_parser to simple' do
|
22
|
-
expect(request.compile).to include(query_parser: 'simple')
|
23
|
-
end
|
24
|
-
end
|
25
|
-
context 'when theres query' do
|
26
|
-
before { request.query.query = "hello world" }
|
27
|
-
it 'should includ query string' do
|
28
|
-
expect(request.compile).to include(query: "hello world")
|
29
|
-
end
|
30
|
-
it 'should default query_parser to simple' do
|
31
|
-
expect(request.compile).to include(query_parser: 'simple')
|
32
|
-
end
|
33
|
-
end
|
34
|
-
context 'when theres query_options' do
|
35
|
-
it 'should include query_options' do
|
36
|
-
request.query_options.fields.concat [QueryOptionsField.new(:price)]
|
37
|
-
expect(request.compile).to include(:query_options)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
context 'when theres filter query' do
|
41
|
-
before { request.filter_query.root.and { tags "sale" } }
|
42
|
-
let(:compiled) { request.filter_query.compile }
|
43
|
-
context 'with query' do
|
44
|
-
before { request.query.query = "hello" }
|
45
|
-
it 'should include filter query' do
|
46
|
-
expect(request.compile).to include(:filter_query)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
context 'without query' do
|
50
|
-
before { request.query.query = "" }
|
51
|
-
it 'should include query instead' do
|
52
|
-
expect(request.compile).to include(:query)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
context 'when theres page' do
|
57
|
-
it 'should include start and size' do
|
58
|
-
expect(request.compile).to include(:start, :size)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
context 'when theres sort' do
|
62
|
-
before { request.sort[:price]= :asc }
|
63
|
-
it 'should include sort' do
|
64
|
-
expect(request.compile).to include(:sort)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|