require './parser' class QueryParserTester describe 'Testing the Parser' do before do @evaluator = Query.new end it 'tests query with only one search term without quotes and without column name' do @result = @evaluator.parse('-123') expect(@result[:DEFAULT_COLUMN]).to eq '-123' end it 'tests query with only one search term with quotes and without column name' do @result = @evaluator.parse('"OR 128"') expect(@result[:DEFAULT_COLUMN]).to eq '"OR 128"' end it 'tests query with one column and search term without quotes' do @result = @evaluator.parse('tag:mta') expect(@result['tag']).to eq 'mta' end it 'tests query with one column and search term with quotes' do @result = @evaluator.parse('tag:"tag 120"') expect(@result['tag']).to eq '"tag 120"' end it 'tests query with two columns connected with OR and search terms without quotes' do @result = @evaluator.parse('tag:mta OR tag:12') @expected_array = [ { 'tag' => 'mta' }, { 'tag' => '12' } ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two columns connected with OR and search terms with quotes' do @result = @evaluator.parse('tag:mta OR tag:"tag 12"') @expected_array = [ { 'tag' => 'mta' }, { 'tag' => '"tag 12"' } ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two columns connected with AND and search terms without quotes' do @result = @evaluator.parse('tag:mta AND tag:12') @expected_array = [ { 'tag' => 'mta' }, { 'tag' => '12' } ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_AND]).to eq @expected_array end it 'tests query with two columns connected with AND and search terms with quotes' do @result = @evaluator.parse('tag:mta and tag:"tag 12"') @expected_array = [ { 'tag' => 'mta' }, { 'tag' => '"tag 12"' } ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_AND]).to eq @expected_array end it 'tests simple query with brackets' do @result = @evaluator.parse('(123)') expect(@result.count).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq '123' end it 'tests simple query with brackets and with a column name' do @result = @evaluator.parse('(name:JF)') expect(@result.count).to eq 1 expect(@result['name']).to eq 'JF' end it 'tests query with OR operator in brackets' do @result = @evaluator.parse('(name:JF or tag:mta)') @expected_array = [ { 'name' => 'JF' }, { 'tag' => 'mta' } ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two simple brackets expressions' do @result = @evaluator.parse('(name:JF) and (-456)') @expected_array = [ { 'name' => 'JF' }, { :DEFAULT_COLUMN => '-456' } ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_AND]).to eq @expected_array end it 'tests query with two brackets expressions' do @result = @evaluator.parse('(name:JF or tag:"tag 0") and (-456)') @expected_array_part_1 = [ { 'name' => 'JF' }, { 'tag' => '"tag 0"' } ] @expected_array_total = [ {:OPERATOR_OR => @expected_array_part_1}, {:DEFAULT_COLUMN => '-456'} ] expect(@result.count).to eq 1 expect(@result[:OPERATOR_AND]).to eq @expected_array_total end it 'tests operator precedence, or - and' do @result1 = @evaluator.parse('tag:mta or name:JF and 12_4') @result2 = @evaluator.parse('tag:mta or (name:JF and 12_4)') expect(@result1).to eq @result2 expect(@result1.length).to eq 1 @expected_array_part_2 = [ {'name' => 'JF'}, {:DEFAULT_COLUMN => '12_4'} ] @expected_array_total = [ {'tag' => 'mta'}, {:OPERATOR_AND => @expected_array_part_2} ] expect(@result1[:OPERATOR_OR]).to eq @expected_array_total end it 'tests operator precedence, and - or' do @result1 = @evaluator.parse('tag:mta and name:JF or 12_4') @result2 = @evaluator.parse('(tag:mta and name:JF) or 12_4') expect(@result1).to eq @result2 expect(@result1.length).to eq 1 @expected_array_part_2 = [ {'tag' => 'mta'}, {'name' => 'JF'} ] @expected_array_total = [ {:OPERATOR_AND => @expected_array_part_2}, {:DEFAULT_COLUMN => '12_4'} ] expect(@result1[:OPERATOR_OR]).to eq @expected_array_total end it 'tests simple query with not operator' do @result = @evaluator.parse('not -54') expect(@result.length).to be 1 expect(@result[:OPERATOR_NOT][:DEFAULT_COLUMN]).to eq '-54' end it 'tests query with mixed NOT and AND logic operator' do @result = @evaluator.parse('name:"some wild name" and not -123-456') @expected_and_array = [ {'name' => '"some wild name"'}, {:OPERATOR_NOT => {:DEFAULT_COLUMN => '-123-456'}} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_AND]).to eq @expected_and_array end it 'tests query with mixed NOT, AND and OR logic operators' do @result = @evaluator.parse('name:"some wild name" or not (tag:mta and -123-456)') @expected_and_array_operands = [ {'tag' => 'mta'}, {:DEFAULT_COLUMN => '-123-456'} ] @expected_or_array_operands = [ {'name' => '"some wild name"'}, {:OPERATOR_NOT => {:OPERATOR_AND => @expected_and_array_operands}} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_or_array_operands end it 'tests query with two default column search terms without quotes and without logical operators' do @result = @evaluator.parse('id-5 -456') @expected_array = [ {:DEFAULT_COLUMN => 'id-5'}, {:DEFAULT_COLUMN => '-456'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two default column search terms with quotes and without logical operators' do @result = @evaluator.parse('"id-5 no Q" -456') @expected_array = [ {:DEFAULT_COLUMN => '"id-5 no Q"'}, {:DEFAULT_COLUMN => '-456'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two default column search terms with quotes on both terms and without logical operators' do @result = @evaluator.parse('"id-5 no Q" "wild id -456"') @expected_array = [ {:DEFAULT_COLUMN => '"id-5 no Q"'}, {:DEFAULT_COLUMN => '"wild id -456"'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with one default column and one non defualt column, search terms without quotes and without logical operators' do @result = @evaluator.parse('tag:mta -456') @expected_array = [ {'tag' => 'mta'}, {:DEFAULT_COLUMN => '-456'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with one default column and one non defualt column, search terms with quotes and without logical operators' do @result = @evaluator.parse('-1-23 name:"WILD name"') @expected_array = [ {:DEFAULT_COLUMN => '-1-23'}, {'name' => '"WILD name"'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two columns, search terms with quotes and without logical operators' do @result = @evaluator.parse('tag:-1-23 name:"WILD name"') @expected_array = [ {'tag' => '-1-23'}, {'name' => '"WILD name"'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with two columns, search terms with quotes on both and without logical operators' do @result = @evaluator.parse('tag:"1 2 3" name:"WILD name"') @expected_array = [ {'tag' => '"1 2 3"'}, {'name' => '"WILD name"'} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests query with three columns, search terms with quotes on both and without logical operators' do @result = @evaluator.parse('tag:"1 2 3" name:"WILD name" name:"ANOTHER wild name"') @expected_array = [ {'tag' => '"1 2 3"'}, {:OPERATOR_OR => [ {'name' => '"WILD name"'}, {'name' => '"ANOTHER wild name"'} ]} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_array end it 'tests complex query' do @result = @evaluator.parse('(device-id:"with space" tag:mta no-quotes-id-123)'\ 'or "id with quotes-5" and ( ("id with q 10" or "id with q 20")'\ 'and ("id with Q 30" "id with Q 40") and not id-without-Q-50)') # (device-id:"with space" tag:mta no-quotes-id-123) or "id with quotes-5" and ( ("id with q 10" or "id with q 20") and ("id with Q 30" "id with Q 40") and not id-without-Q-50) # _____________________A___________________________ or _______B___________ and __________________________________________________C______________________________________________ # (____A1________________ ___A2__ ______A3________) or _______B___________ and ( ____________C1____________________ and ______________C2_______________ and ______C3___________) @A = {:OPERATOR_OR => [ {'device-id' => '"with space"'}, {:OPERATOR_OR => [ {'tag' => 'mta'}, {:DEFAULT_COLUMN => 'no-quotes-id-123'}] } ]} @B = {:DEFAULT_COLUMN => '"id with quotes-5"'} @C1 = {:OPERATOR_OR => [ {:DEFAULT_COLUMN => '"id with q 10"'}, {:DEFAULT_COLUMN => '"id with q 20"'} ]} @C2 = {:OPERATOR_OR => [ {:DEFAULT_COLUMN => '"id with Q 30"'}, {:DEFAULT_COLUMN => '"id with Q 40"'} ]} @C3 = {:OPERATOR_NOT => {:DEFAULT_COLUMN => 'id-without-Q-50'}} @C = {:OPERATOR_AND => [ {:OPERATOR_AND => [ @C1, @C2 ]}, @C3 ]} @expected_final_array_result = [ @A, {:OPERATOR_AND => [ @B, @C ]} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @expected_final_array_result end it 'tests query without column name containing AND word inside without quotes' do @result = @evaluator.parse('land') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq 'land' end it 'tests query without column name containing AND word inside with quotes' do @result = @evaluator.parse('"land"') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq '"land"' end it 'tests query without column name and with word starting with AND without quotes' do @result = @evaluator.parse('andromeda') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq 'andromeda' end it 'tests query without column name and with word starting with AND with quotes' do @result = @evaluator.parse('"andromeda"') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq '"andromeda"' end it 'tests query with column name containing AND word inside' do @result = @evaluator.parse('land:some-search-term') expect(@result.length).to eq 1 expect(@result['land']).to eq 'some-search-term' end it 'tests query with column name starting with AND' do @result = @evaluator.parse('andromeda:some-search-term') expect(@result.length).to eq 1 expect(@result['andromeda']).to eq 'some-search-term' end it 'tests query with search term without quotes containing AND word inside' do @result = @evaluator.parse('name:land') expect(@result.length).to eq 1 expect(@result['name']).to eq 'land' end it 'tests query with search term with quotes containing AND word inside' do @result = @evaluator.parse('name:"land"') expect(@result.length).to eq 1 expect(@result['name']).to eq '"land"' end it 'tests query with search term without quotes and search term starting with AND without quotes' do @result = @evaluator.parse('name:andromeda') expect(@result.length).to eq 1 expect(@result['name']).to eq 'andromeda' end it 'tests query with search term without quotes and search term starting with AND with quotes' do @result = @evaluator.parse('name:"andrew"') expect(@result.length).to eq 1 expect(@result['name']).to eq '"andrew"' end it 'tests query with search term in brackets with AND inside word' do @result = @evaluator.parse('(land)') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq 'land' end it 'tests query with search term in brackets starting with AND' do @result = @evaluator.parse('(andromeda)') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq 'andromeda' end it 'tests query with search term in brackets with AND inside word with quotes' do @result = @evaluator.parse('("land")') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq '"land"' end it 'tests query with search term in brackets starting with AND with quotes' do @result = @evaluator.parse('("andromeda")') expect(@result.length).to eq 1 expect(@result[:DEFAULT_COLUMN]).to eq '"andromeda"' end it 'tests query with multiple search terms starting with AND' do @result = @evaluator.parse('land andrew and andromeda or orlando') @and_array = [ {:DEFAULT_COLUMN=>'andrew'}, {:DEFAULT_COLUMN=>'andromeda'} ] @last_or_array = [ {:OPERATOR_AND => @and_array}, {:DEFAULT_COLUMN => 'orlando'} ] @main_or_array = [ {:DEFAULT_COLUMN => 'land'}, {:OPERATOR_OR => @last_or_array} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @main_or_array end it 'tests query with multiple search terms with dash and underscore chars' do @result = @evaluator.parse('land 123-andrew or -andrew- and not _ornela_ or ornela') @and_array = [ {:DEFAULT_COLUMN=>'-andrew-'}, {:OPERATOR_NOT=>{:DEFAULT_COLUMN => '_ornela_'}} ] @intra_or_array = [ {:DEFAULT_COLUMN => '123-andrew'}, {:OPERATOR_AND => @and_array} ] @last_or_array = [ {:OPERATOR_OR => @intra_or_array}, {:DEFAULT_COLUMN => 'ornela'} ] @main_or_array = [ {:DEFAULT_COLUMN => 'land'}, {:OPERATOR_OR => @last_or_array} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @main_or_array end it 'tests query with multiple search terms with dash and underscore chars under quotes' do @result = @evaluator.parse('"land" "123-andrew" or "-andrew-"') @last_or_array = [ {:DEFAULT_COLUMN => '"123-andrew"'}, {:DEFAULT_COLUMN => '"-andrew-"'} ] @main_or_array = [ {:DEFAULT_COLUMN => '"land"'}, {:OPERATOR_OR => @last_or_array} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @main_or_array end it 'tests query with multiple search terms with mixed and-or-not on start' do @result = @evaluator.parse('sindy andora ornoty notary') @or_array_1 = [ {:DEFAULT_COLUMN=>'ornoty'}, {:DEFAULT_COLUMN=>'notary'} ] @or_array_2 = [ {:DEFAULT_COLUMN => 'andora'}, {:OPERATOR_OR => @or_array_1} ] @main_or_array = [ {:DEFAULT_COLUMN => 'sindy'}, {:OPERATOR_OR => @or_array_2} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @main_or_array end it 'tests query with multiple search terms with mixed and-or-not on start and with logical operators between' do @result = @evaluator.parse('sindy and andora-notary or not ornoty notary') @and_array = [ {:DEFAULT_COLUMN=>'sindy'}, {:DEFAULT_COLUMN=>'andora-notary'} ] @not_or_array = [ {:DEFAULT_COLUMN => 'ornoty'}, {:DEFAULT_COLUMN => 'notary'} ] @main_or_array = [ {:OPERATOR_AND => @and_array}, {:OPERATOR_NOT => { :OPERATOR_OR => @not_or_array }} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_OR]).to eq @main_or_array end it 'tests query with multiple search terms with mixed and-or-not on start and with logical operators between' do @result = @evaluator.parse('(sindy or andora-notary)and not(ornoty notary)') @or_array_1 = [ {:DEFAULT_COLUMN=>'sindy'}, {:DEFAULT_COLUMN=>'andora-notary'} ] @not_or_array = [ {:DEFAULT_COLUMN => 'ornoty'}, {:DEFAULT_COLUMN => 'notary'} ] @main_and_array = [ {:OPERATOR_OR => @or_array_1}, {:OPERATOR_NOT => { :OPERATOR_OR => @not_or_array }} ] expect(@result.length).to eq 1 expect(@result[:OPERATOR_AND]).to eq @main_and_array end end end