Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 18 additions & 32 deletions lib/jay_api/elasticsearch/query_builder/query_clauses.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ class QueryClauses
# If a block is given then +self+ is returned, if no block is given
# then the +bool+ query clause is returned.
def bool
clause ||= boolean_clause || ::JayAPI::Elasticsearch::QueryBuilder::QueryClauses::Bool.new
replace_top_level_clause(clause, force: boolean_query?)
clause = if boolean_query?
top_level_clause
else
self.top_level_clause = ::JayAPI::Elasticsearch::QueryBuilder::QueryClauses::Bool.new
end

if block_given?
yield clause
Expand All @@ -50,7 +53,8 @@ def bool
# @raise [JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError]
# If there is already a top level clause.
def <<(query_clause)
replace_top_level_clause(query_clause)
self.top_level_clause = query_clause
self
end

# @return [Hash] The Hash representation of the Query Clauses set.
Expand Down Expand Up @@ -125,37 +129,19 @@ def negate

private

# Replaces the current top-level clause with the given clause.
# @param [JayAPI::Elasticsearch::QueryBuilder::QueryClauses::QueryClause]
# query_clause The query clause to add.
# @param [Boolean] force Forces the replacement of the top-level clause
# even if there is already a top-level clause in place.
# @return [JayAPI::Elasticsearch::QueryBuilder::QueryClauses] Returns
# itself so that other methods can be chained.
# @raise [JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError]
# If there is already a top level clause and +force+ is +false+.
def replace_top_level_clause(query_clause, force: false)
single_top_level_clause! unless force
@top_level_clause = query_clause
self
end

# @return [JayAPI::Elasticsearch::QueryBuilder::QueryClauses::Bool, nil]
# The current top-level clause if it is a Boolean clause, +nil+
# otherwise.
def boolean_clause
boolean_query? ? top_level_clause : nil
end

# @param [JayAPI::Elasticsearch::QueryBuilder::QueryClauses::QueryClause] clause
# The new top-level query clause.
# @raise [JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError]
# If there is already a top level clause.
def single_top_level_clause!
return unless top_level_clause
# If a top-level query clause already exists.
def top_level_clause=(clause)
if top_level_clause
raise ::JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError,
'Queries can only have one top-level query clause, ' \
'to use multiple clauses add a compound query, ' \
'for example: `bool`'
end

raise ::JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError,
'Queries can only have one top-level query clause, ' \
'to use multiple clauses add a compound query, ' \
'for example: `bool`'
@top_level_clause = clause
end
end
end
Expand Down
28 changes: 21 additions & 7 deletions spec/jay_api/elasticsearch/query_builder/query_clauses_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
method_call
end

it 'returns the same boolean clause that was created before' do
expect(method_call).to be(bool_clause)
end

it 'does not raise any errors' do
expect { method_call }.not_to raise_error
end
Expand All @@ -93,6 +97,16 @@
end
end

shared_examples_for '#<< when there a top-level clause already exists' do
it 'raises a JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError' do
expect { method_call }.to raise_error(
JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError,
'Queries can only have one top-level query clause, to use multiple clauses ' \
'add a compound query, for example: `bool`'
)
end
end

describe '#<<' do
subject(:method_call) { query_clauses << query_clause }

Expand All @@ -103,13 +117,13 @@
context 'when another clause has already been added' do
before { query_clauses.wildcard(field: 'some_field', value: 'a*value') }

it 'raises a JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError' do
expect { method_call }.to raise_error(
JayAPI::Elasticsearch::QueryBuilder::Errors::QueryBuilderError,
'Queries can only have one top-level query clause, to use multiple ' \
'clauses add a compound query, for example: `bool`'
)
end
it_behaves_like '#<< when there a top-level clause already exists'
end

context 'when a boolean clause has already been added' do
before { query_clauses.bool }

it_behaves_like '#<< when there a top-level clause already exists'
end

context 'when no other clause exists yet' do
Expand Down
Loading