saringan 0.3.1 → 0.4.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/README.md +1 -1
- data/lib/saringan/matcher.rb +10 -0
- data/lib/saringan/operator.rb +10 -1
- data/lib/saringan/operators/equal.rb +11 -4
- data/lib/saringan/operators/range.rb +55 -0
- data/lib/saringan/parser.rb +10 -12
- data/lib/saringan/parsers/date_time.rb +35 -0
- data/lib/saringan/parsers/integer_range.rb +3 -0
- data/lib/saringan/qualifier.rb +22 -0
- data/lib/saringan/qualifiers/between.rb +25 -0
- data/lib/saringan/qualifiers/inclusion.rb +25 -0
- data/lib/saringan/qualifiers/range.rb +42 -0
- data/lib/saringan/translator.rb +6 -4
- data/lib/saringan/version.rb +1 -1
- data/lib/saringan.rb +3 -0
- data/spec/operators/equal_spec.rb +3 -0
- data/spec/operators/range_spec.rb +83 -0
- data/spec/parsers/{date_time_range_spec.rb → date_time_spec.rb} +16 -12
- data/spec/qualifiers/between_spec.rb +27 -0
- data/spec/qualifiers/inclusion_spec.rb +27 -0
- data/spec/qualifiers/range_spec.rb +48 -0
- data/spec/support/spec_helper.rb +1 -0
- data/spec/terms_spec.rb +3 -0
- data/spec/translator_spec.rb +12 -1
- metadata +33 -10
- data/lib/saringan/operators.rb +0 -1
- data/lib/saringan/parsers/date_time_range.rb +0 -27
- data/lib/saringan/parsers/range.rb +0 -40
- data/lib/saringan/parsers.rb +0 -4
- data/spec/parsers/range_spec.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eb1091f0f3aae7508e4012b7ae7b820c237beff838c2535e022e18745b91513
|
4
|
+
data.tar.gz: be906a1fe3e01bbb26b04741e5cd12e25184d1184063b3711046488de16dbcc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddd2030b69479a87b2100ee3fe65adaaee69807b03f362bfdb2bce31366c28fee8373c7df3c116d9f15213ffca3ae98ec7d34e1a4acd6779f990587ce6c8eba7
|
7
|
+
data.tar.gz: b781ae99878fbd2e3377b72c9f855864c86606115d720b2ae8ed9e44de2883207a3073669597a138dadd82fdd8ffc2bb8c6bd3b1923aa97630ec3ccf2987e015
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Saringan
|
1
|
+
# Saringan · [](https://travis-ci.org/reinaldooli/saringan) [](https://github.com/reinaldooli/saringan/blob/master/MIT-LICENSE) [](https://badge.fury.io/rb/saringan)
|
2
2
|
|
3
3
|
Translate query strings to activerecord query parameters.
|
4
4
|
|
data/lib/saringan/operator.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require "saringan/operators/equal"
|
5
|
+
require "saringan/operators/range"
|
2
6
|
|
3
7
|
module Saringan
|
4
8
|
class Operator
|
5
9
|
class << self
|
6
10
|
def parse(term)
|
7
11
|
return equal.to_h(term) if equal.match?(term)
|
12
|
+
return range.to_h(term) if range.match?(term)
|
8
13
|
end
|
9
14
|
|
10
15
|
private
|
@@ -12,6 +17,10 @@ module Saringan
|
|
12
17
|
def equal
|
13
18
|
Saringan::Operators::Equal
|
14
19
|
end
|
20
|
+
|
21
|
+
def range
|
22
|
+
Saringan::Operators::Range
|
23
|
+
end
|
15
24
|
end
|
16
25
|
end
|
17
26
|
end
|
@@ -1,12 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
1
4
|
require 'saringan/parser'
|
5
|
+
require 'saringan/matcher'
|
2
6
|
|
3
7
|
module Saringan
|
4
8
|
module Operators
|
5
9
|
class Equal
|
10
|
+
extend Saringan::Matcher
|
6
11
|
|
7
12
|
OP_EQUAL = /::/
|
8
13
|
|
9
14
|
class << self
|
15
|
+
|
16
|
+
# TODO: Create an absolute qualifier
|
10
17
|
def to_h(term)
|
11
18
|
splitted = split(term)
|
12
19
|
{ "#{splitted[:key]}": parser.parse(splitted[:value]) }
|
@@ -17,15 +24,15 @@ module Saringan
|
|
17
24
|
{ query: "#{splitted[:key]} = ?", params: splitted[:value] }
|
18
25
|
end
|
19
26
|
|
20
|
-
def match?(term)
|
21
|
-
term =~ OP_EQUAL
|
22
|
-
end
|
23
|
-
|
24
27
|
def split(term)
|
25
28
|
splitted = term.split(OP_EQUAL)
|
26
29
|
{ key: splitted[0], value: splitted[1] }
|
27
30
|
end
|
28
31
|
|
32
|
+
def matcher
|
33
|
+
OP_EQUAL
|
34
|
+
end
|
35
|
+
|
29
36
|
private
|
30
37
|
|
31
38
|
def parser
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'saringan/matcher'
|
5
|
+
require 'saringan/parser'
|
6
|
+
require 'saringan/qualifiers/range'
|
7
|
+
|
8
|
+
module Saringan
|
9
|
+
module Operators
|
10
|
+
class Range
|
11
|
+
extend Saringan::Matcher
|
12
|
+
|
13
|
+
OP_RANGE = /:>:/
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def matcher
|
17
|
+
OP_RANGE
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_h(term)
|
21
|
+
splitted = split(term)
|
22
|
+
parsed = parser(splitted[:value])
|
23
|
+
qualified = qualify(parsed[:value], parsed[:parser])
|
24
|
+
|
25
|
+
case qualified[:type]
|
26
|
+
when :in
|
27
|
+
{ "#{splitted[:key]}": qualified[:value] }
|
28
|
+
when :between
|
29
|
+
{ "#{splitted[:key]}": qualified[:value][0]..qualified[:value][1] }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def split(term)
|
34
|
+
splitted = term.split(OP_RANGE)
|
35
|
+
{ key: splitted[0], value: splitted[1] }
|
36
|
+
end
|
37
|
+
|
38
|
+
def qualify(value, parser)
|
39
|
+
qualifier.qualify(value, parser)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def qualifier
|
45
|
+
Saringan::Qualifiers::Range
|
46
|
+
end
|
47
|
+
|
48
|
+
def parser(value)
|
49
|
+
Saringan::Parser.build(value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/saringan/parser.rb
CHANGED
@@ -1,27 +1,25 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'saringan/parsers/date_time'
|
2
5
|
|
3
6
|
module Saringan
|
4
7
|
class Parser
|
5
8
|
class << self
|
6
9
|
def parse(value)
|
7
|
-
return
|
8
|
-
return datetime_range_parser(value) if date_time_range.match?(value)
|
10
|
+
return date_time.parse(value) if date_time.match?(value)
|
9
11
|
value
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
14
|
+
def build(value)
|
15
|
+
return {value: date_time.clean(value), parser: date_time} if date_time.match?(value)
|
16
|
+
{ value: value, parser: nil }
|
15
17
|
end
|
16
18
|
|
17
19
|
private
|
18
20
|
|
19
|
-
def
|
20
|
-
Saringan::Parsers::
|
21
|
-
end
|
22
|
-
|
23
|
-
def date_time_range
|
24
|
-
Saringan::Parsers::DateTimeRange
|
21
|
+
def date_time
|
22
|
+
Saringan::Parsers::DateTime
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'active_support/core_ext/time'
|
5
|
+
require 'active_support/core_ext/date_time'
|
6
|
+
require 'saringan/matcher'
|
7
|
+
|
8
|
+
module Saringan
|
9
|
+
module Parsers
|
10
|
+
class DateTime
|
11
|
+
extend Saringan::Matcher
|
12
|
+
|
13
|
+
MATCHER = /^dt\[(.+)\]$/
|
14
|
+
FORMAT = '%Y-%m-%d %H:%M:%S'
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def clean(value)
|
18
|
+
value.gsub(/^dt\[|\]$/, '')
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse(value)
|
22
|
+
cleaned = clean(value)
|
23
|
+
date = ::DateTime.strptime(cleaned, FORMAT)
|
24
|
+
::DateTime.new date.year, date.month, date.day, date.hour, date.min, \
|
25
|
+
date.sec, ::DateTime.current.zone
|
26
|
+
end
|
27
|
+
alias_method :to_proc, :parse
|
28
|
+
|
29
|
+
def matcher
|
30
|
+
MATCHER
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'saringan/qualifiers/range'
|
5
|
+
|
6
|
+
module Saringan
|
7
|
+
class Qualifier
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def qualify(value)
|
11
|
+
range.parse_value(value) if range.match?(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def range
|
17
|
+
Saringan::Qualifiers::Range
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'saringan/matcher'
|
5
|
+
|
6
|
+
module Saringan
|
7
|
+
module Qualifiers
|
8
|
+
class Between
|
9
|
+
extend Saringan::Matcher
|
10
|
+
|
11
|
+
QL_BETWEEN = /\~+/
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def matcher
|
15
|
+
QL_BETWEEN
|
16
|
+
end
|
17
|
+
|
18
|
+
def qualify(value, parser = nil)
|
19
|
+
splitted = value.split(QL_BETWEEN)[0,2]
|
20
|
+
splitted.map{|v| parser.nil? ? v : parser.parse(v)}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'saringan/matcher'
|
5
|
+
|
6
|
+
module Saringan
|
7
|
+
module Qualifiers
|
8
|
+
class Inclusion
|
9
|
+
extend Saringan::Matcher
|
10
|
+
|
11
|
+
QL_INCLUSION = /\;+/
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def qualify(value, parser = nil)
|
15
|
+
splitted = value.split(QL_INCLUSION)
|
16
|
+
parser.nil? ? splitted : splitted.map(&parser)
|
17
|
+
end
|
18
|
+
|
19
|
+
def matcher
|
20
|
+
QL_INCLUSION
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'saringan/matcher'
|
2
|
+
require 'saringan/qualifiers/inclusion'
|
3
|
+
require 'saringan/qualifiers/between'
|
4
|
+
|
5
|
+
module Saringan
|
6
|
+
module Qualifiers
|
7
|
+
class Range
|
8
|
+
extend Saringan::Matcher
|
9
|
+
|
10
|
+
QL_RANGE = /(^\[(.+)\])/
|
11
|
+
QL_REPLACER = /(^\[|\]$)/
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def matcher
|
15
|
+
QL_RANGE
|
16
|
+
end
|
17
|
+
|
18
|
+
def qualify(value, parser)
|
19
|
+
cleaned = value.gsub(QL_REPLACER, '')
|
20
|
+
|
21
|
+
if inclusion.match?(value)
|
22
|
+
{ type: :in, value: inclusion.qualify(cleaned, parser) }
|
23
|
+
elsif between.match?(value)
|
24
|
+
{ type: :between, value: between.qualify(cleaned, parser) }
|
25
|
+
else
|
26
|
+
raise ArgumentError.new('Value is not a range')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def inclusion
|
33
|
+
Saringan::Qualifiers::Inclusion
|
34
|
+
end
|
35
|
+
|
36
|
+
def between
|
37
|
+
Saringan::Qualifiers::Between
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/saringan/translator.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
1
4
|
require 'saringan/operator'
|
2
5
|
|
3
6
|
module Saringan
|
@@ -5,10 +8,9 @@ module Saringan
|
|
5
8
|
class << self
|
6
9
|
def translate(query)
|
7
10
|
terms = term.split(query)
|
8
|
-
parsed =
|
9
|
-
|
10
|
-
|
11
|
-
(parsed.size > 1) ? parsed : parsed.first
|
11
|
+
parsed = {}
|
12
|
+
terms.each{|term| parsed.merge!(operator.parse(term))}
|
13
|
+
parsed
|
12
14
|
end
|
13
15
|
|
14
16
|
private
|
data/lib/saringan/version.rb
CHANGED
data/lib/saringan.rb
CHANGED
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'support/spec_helper'
|
5
|
+
|
6
|
+
describe Saringan::Operators::Range, type: :operator do
|
7
|
+
let(:operator) { described_class }
|
8
|
+
|
9
|
+
describe '#qualify' do
|
10
|
+
context 'for inclusion range' do
|
11
|
+
it 'return values qualified as array' do
|
12
|
+
value = 'val;val;val'
|
13
|
+
qualified = operator.qualify(value, nil)
|
14
|
+
expect(qualified[:value]).to have(3).items
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'qualify values as inclusion' do
|
18
|
+
value = 'val;val;val'
|
19
|
+
qualified = operator.qualify(value, nil)
|
20
|
+
expect(qualified[:type]).to eq(:in)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'qualified values was not changed' do
|
24
|
+
value = 'val;val;val'
|
25
|
+
qualified = operator.qualify(value, nil)
|
26
|
+
expect(qualified[:value]).to eq(['val', 'val', 'val'])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'for between range' do
|
31
|
+
it 'return values qualified as array' do
|
32
|
+
value = 'val~val'
|
33
|
+
qualified = operator.qualify(value, nil)
|
34
|
+
expect(qualified[:value]).to have(2).items
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'qualify values as between' do
|
38
|
+
value = 'val~val'
|
39
|
+
qualified = operator.qualify(value, nil)
|
40
|
+
expect(qualified[:type]).to eq(:between)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'between qualified values has only from/to values' do
|
44
|
+
value = 'val1~val2~val_'
|
45
|
+
qualified = operator.qualify(value, nil)
|
46
|
+
expect(qualified[:value]).to eq(['val1', 'val2'])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#split' do
|
52
|
+
it 'split term as key => value hash' do
|
53
|
+
term = 'status:>:[todo;doing;done]'
|
54
|
+
expect(operator.split(term)).to eq({ key: 'status', value: '[todo;doing;done]'})
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'splitted key' do
|
58
|
+
it 'match term key' do
|
59
|
+
term = 'status:>:[todo;doing;done]'
|
60
|
+
splitted = operator.split(term)
|
61
|
+
expect(splitted[:key]).to eq('status')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'splitted value' do
|
66
|
+
it 'match term value' do
|
67
|
+
term = 'status:>:[todo;doing;done]'
|
68
|
+
splitted = operator.split(term)
|
69
|
+
expect(splitted[:value]).to eq('[todo;doing;done]')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#to_h' do
|
75
|
+
context 'for inclusion range' do
|
76
|
+
it 'value must be an array' do
|
77
|
+
term = 'status:>:[todo;doing;done]'
|
78
|
+
hash = operator.to_h(term)
|
79
|
+
expect(hash).to eq({ status: ['todo', 'doing', 'done'] })
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
2
4
|
require 'support/spec_helper'
|
3
5
|
|
4
|
-
describe Saringan::Parsers::
|
5
|
-
let(:parser) {
|
6
|
+
describe Saringan::Parsers::DateTime, type: :parsers do
|
7
|
+
let(:parser) { described_class }
|
6
8
|
let(:from ) { DateTime.new(2018, 06, 01, 00, 00, 00, DateTime.current.zone) }
|
7
9
|
let(:to) { DateTime.new(2018, 06, 30, 23, 59, 59, DateTime.current.zone) }
|
8
10
|
|
@@ -25,17 +27,19 @@ describe Saringan::Parsers::DateTimeRange do
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
describe '#
|
29
|
-
it 'should
|
30
|
-
value = '
|
31
|
-
expect(parser.
|
30
|
+
describe '#parse' do
|
31
|
+
it 'should parse value to DateTime' do
|
32
|
+
value = '2018-06-01 00:00:00'
|
33
|
+
expect(parser.parse(value)).to eq(from)
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
describe '#to_h' do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
37
|
+
# describe '#to_h' do
|
38
|
+
# context 'using between translator' do
|
39
|
+
# it 'should translate value into from/to hash' do
|
40
|
+
# value = 'dt[2018-06-01 00:00:00|2018-06-30 23:59:59]'
|
41
|
+
# expect(parser.to_h(value)[:value]).to eq([from, to])
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# end
|
41
45
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'support/spec_helper'
|
5
|
+
|
6
|
+
describe Saringan::Qualifiers::Between, type: :qualifier do
|
7
|
+
let(:qualifier) { described_class }
|
8
|
+
|
9
|
+
describe '#match?' do
|
10
|
+
it 'matches between values' do
|
11
|
+
value = 'val~ val~ val'
|
12
|
+
expect(qualifier.match?(value)).to be_truthy
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'not matches non between value' do
|
16
|
+
value = 'val ; val ; val'
|
17
|
+
expect(qualifier.match?(value)).to be_falsy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#qualify' do
|
22
|
+
it 'parse value to array' do
|
23
|
+
value = 'val~val~val'
|
24
|
+
expect(qualifier.qualify(value)).to have(2).items
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'support/spec_helper'
|
5
|
+
|
6
|
+
describe Saringan::Qualifiers::Inclusion, type: :qualifier do
|
7
|
+
let(:qualifier) { described_class }
|
8
|
+
|
9
|
+
describe '#match?' do
|
10
|
+
it 'matches inclusion value' do
|
11
|
+
value = 'val; val; val'
|
12
|
+
expect(qualifier.match?(value)).to be_truthy
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'not matches non inclusion value' do
|
16
|
+
value = 'val \ val \ val'
|
17
|
+
expect(qualifier.match?(value)).to be_falsy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#qualify' do
|
22
|
+
it 'parse value to array' do
|
23
|
+
value = 'val;val;val'
|
24
|
+
expect(qualifier.qualify(value)).to have(3).items
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'support/spec_helper'
|
5
|
+
|
6
|
+
describe Saringan::Qualifiers::Range, type: :qualifier do
|
7
|
+
let(:qualifier) { described_class }
|
8
|
+
|
9
|
+
describe '#match?' do
|
10
|
+
it 'match inclusion range value' do
|
11
|
+
value = '[val; val; val]'
|
12
|
+
expect(qualifier.match?(value)).to be_truthy
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'match between range value' do
|
16
|
+
value = '[val\val]'
|
17
|
+
expect(qualifier.match?(value)).to be_truthy
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'not match unclosed range value' do
|
21
|
+
value = '[value'
|
22
|
+
expect(qualifier.match?(value)).to be_falsy
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'not match non range value' do
|
26
|
+
value = '(value)'
|
27
|
+
expect(qualifier.match?(value)).to be_falsy
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#qualify' do
|
32
|
+
context 'for inclusion values' do
|
33
|
+
it 'parse inclusion values as array' do
|
34
|
+
value = 'val; val; val'
|
35
|
+
parsed = qualifier.qualify(value, nil)
|
36
|
+
expect(parsed[:value]).to have(3).items
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'for between values' do
|
41
|
+
it 'parse between values as from/to hash' do
|
42
|
+
value = 'val~val~val'
|
43
|
+
parsed = qualifier.qualify(value, nil)
|
44
|
+
expect(parsed[:value]).to have(2).items
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/support/spec_helper.rb
CHANGED
data/spec/terms_spec.rb
CHANGED
data/spec/translator_spec.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
1
4
|
require 'support/spec_helper'
|
2
5
|
|
3
6
|
describe Saringan::Translator do
|
@@ -5,7 +8,7 @@ describe Saringan::Translator do
|
|
5
8
|
|
6
9
|
describe '#translate' do
|
7
10
|
context 'for date time ranges' do
|
8
|
-
let(:query) { 'created_at
|
11
|
+
let(:query) { 'created_at:>:dt[2018-06-01 00:00:00~2018-06-30 23:59:59]' }
|
9
12
|
|
10
13
|
it 'should translate date time query string to ruby hash' do
|
11
14
|
from = DateTime.new(2018, 06, 01, 00, 00, 00, DateTime.current.zone)
|
@@ -24,5 +27,13 @@ describe Saringan::Translator do
|
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
30
|
+
|
31
|
+
context 'with multiple filters' do
|
32
|
+
let(:query) { 'name::john,age::18' }
|
33
|
+
|
34
|
+
it 'translate query string to ruby rash' do
|
35
|
+
expect(translator.translate(query)).to eq({ name: 'john', age: '18' })
|
36
|
+
end
|
37
|
+
end
|
27
38
|
end
|
28
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saringan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reinaldo Olivera (k1ng)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-collection_matchers
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.1'
|
69
83
|
description: Simple way to send filter parameters to rails models.
|
70
84
|
email:
|
71
85
|
executables: []
|
@@ -75,21 +89,27 @@ files:
|
|
75
89
|
- MIT-LICENSE
|
76
90
|
- README.md
|
77
91
|
- lib/saringan.rb
|
92
|
+
- lib/saringan/matcher.rb
|
78
93
|
- lib/saringan/operator.rb
|
79
|
-
- lib/saringan/operators.rb
|
80
94
|
- lib/saringan/operators/equal.rb
|
95
|
+
- lib/saringan/operators/range.rb
|
81
96
|
- lib/saringan/parser.rb
|
82
|
-
- lib/saringan/parsers.rb
|
83
|
-
- lib/saringan/parsers/date_time_range.rb
|
97
|
+
- lib/saringan/parsers/date_time.rb
|
84
98
|
- lib/saringan/parsers/integer_range.rb
|
85
|
-
- lib/saringan/
|
99
|
+
- lib/saringan/qualifier.rb
|
100
|
+
- lib/saringan/qualifiers/between.rb
|
101
|
+
- lib/saringan/qualifiers/inclusion.rb
|
102
|
+
- lib/saringan/qualifiers/range.rb
|
86
103
|
- lib/saringan/term.rb
|
87
104
|
- lib/saringan/translator.rb
|
88
105
|
- lib/saringan/version.rb
|
89
106
|
- spec/operators/equal_spec.rb
|
90
|
-
- spec/
|
107
|
+
- spec/operators/range_spec.rb
|
108
|
+
- spec/parsers/date_time_spec.rb
|
91
109
|
- spec/parsers/integer_range_spec.rb
|
92
|
-
- spec/
|
110
|
+
- spec/qualifiers/between_spec.rb
|
111
|
+
- spec/qualifiers/inclusion_spec.rb
|
112
|
+
- spec/qualifiers/range_spec.rb
|
93
113
|
- spec/saringan_spec.rb
|
94
114
|
- spec/support/spec_helper.rb
|
95
115
|
- spec/terms_spec.rb
|
@@ -119,11 +139,14 @@ signing_key:
|
|
119
139
|
specification_version: 4
|
120
140
|
summary: Simple way to send filter parameters to rails models.
|
121
141
|
test_files:
|
142
|
+
- spec/qualifiers/inclusion_spec.rb
|
143
|
+
- spec/qualifiers/between_spec.rb
|
144
|
+
- spec/qualifiers/range_spec.rb
|
145
|
+
- spec/operators/range_spec.rb
|
122
146
|
- spec/operators/equal_spec.rb
|
123
147
|
- spec/terms_spec.rb
|
124
148
|
- spec/support/spec_helper.rb
|
125
149
|
- spec/translator_spec.rb
|
126
|
-
- spec/parsers/date_time_range_spec.rb
|
127
150
|
- spec/parsers/integer_range_spec.rb
|
128
|
-
- spec/parsers/
|
151
|
+
- spec/parsers/date_time_spec.rb
|
129
152
|
- spec/saringan_spec.rb
|
data/lib/saringan/operators.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'saringan/operators/equal'
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'active_support/core_ext/time'
|
3
|
-
require 'active_support/core_ext/date_time'
|
4
|
-
|
5
|
-
module Saringan
|
6
|
-
module Parsers
|
7
|
-
class DateTimeRange < Range
|
8
|
-
MATCHER = /^dt\[(.+)\]$/
|
9
|
-
FORMAT = '%Y-%m-%d %H:%M:%S'
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def split(value)
|
13
|
-
splitted = super(value)
|
14
|
-
splitted.map do |part|
|
15
|
-
date = DateTime.strptime(part, FORMAT)
|
16
|
-
DateTime.new date.year, date.month, date.day, date.hour, date.min, \
|
17
|
-
date.sec, DateTime.current.zone
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def clean(value)
|
22
|
-
value.gsub(/^dt\[/, '').gsub(/\]$/, '')
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# -*- encoding: utf-8 -*-
|
3
|
-
|
4
|
-
module Saringan
|
5
|
-
module Parsers
|
6
|
-
class Range
|
7
|
-
MATCHER = /^\[(.+)\]$/
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def match?(value)
|
11
|
-
value =~ matcher
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_h(value)
|
15
|
-
splitted = split(value)
|
16
|
-
{ from: parse_value(splitted[0]), to: parse_value(splitted[1]) }
|
17
|
-
end
|
18
|
-
|
19
|
-
def split(value)
|
20
|
-
cleaned = clean(value)
|
21
|
-
cleaned.split('|')
|
22
|
-
end
|
23
|
-
|
24
|
-
def clean(value)
|
25
|
-
value.gsub(/^\[/, '').gsub(/\]$/, '')
|
26
|
-
end
|
27
|
-
|
28
|
-
def parse_value(value)
|
29
|
-
value
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def matcher
|
35
|
-
self::MATCHER
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
data/lib/saringan/parsers.rb
DELETED
data/spec/parsers/range_spec.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'support/spec_helper'
|
2
|
-
|
3
|
-
describe Saringan::Parsers::Range do
|
4
|
-
let(:parser){ Saringan::Parsers::Range }
|
5
|
-
|
6
|
-
describe '#match?' do
|
7
|
-
it 'should match range value' do
|
8
|
-
value = '[1|10]'
|
9
|
-
expect(parser.match?(value)).to be_truthy
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should not match non range value' do
|
13
|
-
value = '[1|10'
|
14
|
-
expect(parser.match?(value)).to be_falsy
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '#clean' do
|
19
|
-
it 'should remove range markup from value' do
|
20
|
-
value = '[1|3]'
|
21
|
-
expect(parser.clean(value)).to eq('1|3')
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#splt' do
|
26
|
-
it 'should separate range in from/to array' do
|
27
|
-
value = '[1|3]'
|
28
|
-
expect(parser.split(value)).to eq(["1", "3"])
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|