chuckya/spec/lib/search_query_parser_spec.rb

240 lines
5.4 KiB
Ruby
Raw Normal View History

2023-04-06 03:24:44 +09:00
# frozen_string_literal: true
require 'rails_helper'
describe SearchQueryParser do
subject(:parser) { described_class.new }
describe '#parse' do
context 'when given a simple text query' do
let(:query) { 'text' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
term: 'text',
},
},
]
)
end
end
context 'when given a query with a remote account name' do
let(:query) { 'user@domain.tld' }
it 'parses the account name as a term' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
term: 'user@domain.tld',
},
},
]
)
end
end
context 'when given a query with an @-prefixed remote account name' do
let(:query) { '@user@domain.tld' }
it 'parses the account name as a term' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
term: '@user@domain.tld',
},
},
]
)
end
end
context 'when given a query with an @-prefixed local account name' do
let(:query) { '@user' }
it 'parses the account name as a term' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
term: '@user',
},
},
]
)
end
end
context 'when given a quoted phrase query' do
let(:query) { '"a phrase"' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
phrase: 'a phrase',
},
},
]
)
end
end
context 'when given a malformed quoted phrase query' do
let(:query) { '"a phrase' }
it 'raises a Parslet exception' do
expect { parser.parse(query) }.to raise_exception Parslet::ParseFailed
end
end
context 'when given a text query with an operator' do
let(:query) { '+text' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
operator: '+',
term: 'text',
},
},
]
)
end
end
context 'when given a prefix query' do
let(:query) { 'from:user' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
prefix: 'from',
term: 'user',
},
},
]
)
end
end
context 'when given a query containing a prefix with nothing after it' do
let(:query) { 'from:' }
it 'raises a Parslet exception' do
expect { parser.parse(query) }.to raise_exception Parslet::ParseFailed
end
end
context 'when given a prefix query with an operator' do
let(:query) { '-from:user' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
operator: '-',
prefix: 'from',
term: 'user',
},
},
]
)
end
end
context 'when given a prefix query with a remote account name' do
let(:query) { 'from:user@domain.tld' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
prefix: 'from',
term: 'user@domain.tld',
},
},
]
)
end
end
context 'when given a mixed text and hashtag query' do
let(:query) { 'text #hashtag' }
it 'parses the query' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
term: 'text',
},
},
{
clause: {
hashtag: 'hashtag',
},
},
]
)
end
end
context 'when given a bare URL query' do
let(:query) { 'https://example.org/' }
it 'parses the URL as a term' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
term: 'https://example.org/',
},
},
]
)
end
end
context 'when given a quoted URL query' do
let(:query) { '"https://example.org/"' }
it 'parses the URL as a phrase' do
parsed_query = parser.parse(query)
expect(parsed_query).to match(
query: [
{
clause: {
phrase: 'https://example.org/',
},
},
]
)
end
end
end
end