stretchy 0.4.0 → 0.4.1
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/.gitignore +2 -1
- data/.ruby-version +1 -0
- data/lib/stretchy/boosts/base.rb +2 -3
- data/lib/stretchy/boosts/field_decay_boost.rb +23 -19
- data/lib/stretchy/boosts/filter_boost.rb +6 -3
- data/lib/stretchy/boosts/random_boost.rb +7 -4
- data/lib/stretchy/builders/boost_builder.rb +1 -1
- data/lib/stretchy/builders/filter_builder.rb +55 -0
- data/lib/stretchy/builders/match_builder.rb +41 -43
- data/lib/stretchy/builders/query_builder.rb +37 -0
- data/lib/stretchy/builders/shell_builder.rb +53 -0
- data/lib/stretchy/builders/where_builder.rb +88 -159
- data/lib/stretchy/builders.rb +3 -0
- data/lib/stretchy/clauses/base.rb +33 -78
- data/lib/stretchy/clauses/boost_clause.rb +10 -10
- data/lib/stretchy/clauses/boost_match_clause.rb +3 -3
- data/lib/stretchy/clauses/boost_where_clause.rb +5 -5
- data/lib/stretchy/clauses/match_clause.rb +5 -24
- data/lib/stretchy/clauses/where_clause.rb +23 -42
- data/lib/stretchy/errors/validation_error.rb +17 -0
- data/lib/stretchy/errors.rb +1 -1
- data/lib/stretchy/filters/and_filter.rb +5 -1
- data/lib/stretchy/filters/base.rb +2 -2
- data/lib/stretchy/filters/bool_filter.rb +10 -4
- data/lib/stretchy/filters/exists_filter.rb +5 -1
- data/lib/stretchy/filters/geo_filter.rb +13 -7
- data/lib/stretchy/filters/not_filter.rb +5 -2
- data/lib/stretchy/filters/or_filter.rb +4 -1
- data/lib/stretchy/filters/query_filter.rb +5 -1
- data/lib/stretchy/filters/range_filter.rb +10 -5
- data/lib/stretchy/filters/terms_filter.rb +8 -2
- data/lib/stretchy/queries/base.rb +2 -2
- data/lib/stretchy/queries/bool_query.rb +12 -0
- data/lib/stretchy/queries/filtered_query.rb +8 -3
- data/lib/stretchy/queries/function_score_query.rb +25 -32
- data/lib/stretchy/queries/match_query.rb +10 -3
- data/lib/stretchy/results/base.rb +9 -23
- data/lib/stretchy/types/base.rb +2 -2
- data/lib/stretchy/types/geo_point.rb +15 -6
- data/lib/stretchy/types/range.rb +24 -6
- data/lib/stretchy/utils/logger.rb +10 -5
- data/lib/stretchy/utils/validation.rb +77 -0
- data/lib/stretchy/utils.rb +1 -1
- data/lib/stretchy/version.rb +1 -1
- data/lib/stretchy.rb +3 -0
- data/lib/stretchy_validations.rb +10 -0
- data/lib/validation/rule/decay.rb +20 -0
- data/lib/validation/rule/distance.rb +20 -0
- data/lib/validation/rule/field.rb +22 -0
- data/lib/validation/rule/inclusion.rb +33 -0
- data/lib/validation/rule/latitude.rb +21 -0
- data/lib/validation/rule/longitude.rb +22 -0
- data/lib/validation/rule/one_of.rb +22 -0
- data/lib/validation/rule/required.rb +26 -0
- data/lib/validation/rule/responds_to.rb +23 -0
- data/lib/validation/rule/type.rb +41 -0
- data/stretchy.gemspec +2 -0
- metadata +48 -5
- data/lib/stretchy/errors/contract_error.rb +0 -5
- data/lib/stretchy/utils/contract.rb +0 -120
@@ -1,120 +0,0 @@
|
|
1
|
-
module Stretchy
|
2
|
-
module Utils
|
3
|
-
module Contract
|
4
|
-
|
5
|
-
ASSERTIONS = [:type, :responds_to, :in, :matches, :required]
|
6
|
-
DISTANCE_FORMAT = /^(\d+)(km|mi)$/
|
7
|
-
DECAY_FUNCTIONS = [:gauss, :linear, :exp]
|
8
|
-
|
9
|
-
def self.included(base)
|
10
|
-
base.send(:extend, ClassMethods)
|
11
|
-
end
|
12
|
-
|
13
|
-
def validate!
|
14
|
-
self.class.contracts.each do |name, options|
|
15
|
-
value = instance_variable_get("@#{name}")
|
16
|
-
next if value.nil? && !options[:required]
|
17
|
-
|
18
|
-
if options[:array]
|
19
|
-
self.class.assert_type(name, value, type: Array)
|
20
|
-
self.class.assert_required(name, value, {}) if options[:required]
|
21
|
-
end
|
22
|
-
|
23
|
-
ASSERTIONS.each do |assertion|
|
24
|
-
assertion_method = "assert_#{assertion}"
|
25
|
-
if options[:array]
|
26
|
-
value.each {|v| self.class.send(assertion_method, name, v, options) } unless options[assertion].nil?
|
27
|
-
else
|
28
|
-
self.class.send(assertion_method, name, value, options) unless options[assertion].nil?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def require_one(options = {})
|
35
|
-
if options.values.all?{|v| self.class.is_empty?(v) }
|
36
|
-
raise Stretchy::Errors::ContractError.new("One of #{options.keys.join(', ')} must be present, found: #{options}")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
module ClassMethods
|
41
|
-
|
42
|
-
attr_reader :contracts
|
43
|
-
|
44
|
-
def is_empty?(value)
|
45
|
-
value.nil? ||
|
46
|
-
(value.respond_to?(:any?) && !value.any?) ||
|
47
|
-
(value.respond_to?(:length) && value.length == 0)
|
48
|
-
end
|
49
|
-
|
50
|
-
def contract(var, options = {})
|
51
|
-
@contracts ||= {}
|
52
|
-
if var.is_a?(Hash)
|
53
|
-
var.each {|k,v| @contracts[k] = v }
|
54
|
-
else
|
55
|
-
@contracts[var] = options
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def fail_assertion(msg)
|
60
|
-
raise Stretchy::Errors::ContractError.new(msg)
|
61
|
-
end
|
62
|
-
|
63
|
-
def assert_required(name, value, options)
|
64
|
-
msg = "Expected to have param #{name}, but got an #{value.inspect}"
|
65
|
-
fail_assertion(msg) if is_empty?(value)
|
66
|
-
end
|
67
|
-
|
68
|
-
def assert_type(name, value, options)
|
69
|
-
type = options[:type]
|
70
|
-
case type
|
71
|
-
when :distance
|
72
|
-
msg = "Expected #{name} to be a distance measure, but #{value} is not a valid distance"
|
73
|
-
fail_assertion(msg) unless String(value).match(DISTANCE_FORMAT)
|
74
|
-
when :lat
|
75
|
-
msg = "Expected #{name} to be between 90 and -90, but was #{value}"
|
76
|
-
value = Float(value) rescue nil
|
77
|
-
fail_assertion(msg) unless value && value <= 90 && value >= -90
|
78
|
-
when :lng
|
79
|
-
msg = "Expected #{name} to be between 180 and -180, but was #{value}"
|
80
|
-
value = Float(value) rescue nil
|
81
|
-
fail_assertion(msg) unless value && value.to_f <= 180 && value.to_f >= -180
|
82
|
-
when :field
|
83
|
-
msg = "Expected #{name} to be a string, symbol, or number, but got #{value.class.name}"
|
84
|
-
fail_assertion(msg) unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(Numeric)
|
85
|
-
|
86
|
-
msg = "Expected #{name} to be a string, symbol, or number, but was blank"
|
87
|
-
fail_assertion(msg) if value.is_a?(String) && value.empty?
|
88
|
-
when :decay
|
89
|
-
msg = "Expected #{name} to be one of #{DECAY_FUNCTIONS.join(', ')}, but got #{value}"
|
90
|
-
fail_assertion(msg) unless DECAY_FUNCTIONS.any?{|f| f == value || f.to_s == value }
|
91
|
-
when Array
|
92
|
-
msg = "Expected #{name} to be one of #{type.map{|t| t.name}}, but got #{value.class.name}"
|
93
|
-
fail_assertion(msg) unless type.any?{|t| value.is_a?(t)}
|
94
|
-
else
|
95
|
-
msg = "Expected #{name} to be of type #{type}, but found #{value.class.name}"
|
96
|
-
fail_assertion(msg) unless value.is_a?(type)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def assert_responds_to(name, value, options)
|
101
|
-
method = options[:responds_to]
|
102
|
-
msg = "Expected #{name} to respond_to #{method}, but #{value.class.name} does not"
|
103
|
-
fail_assertion(msg) unless value.respond_to?(method)
|
104
|
-
end
|
105
|
-
|
106
|
-
def assert_in(name, value, options)
|
107
|
-
collection = options[:in]
|
108
|
-
msg = "Expected #{name} to be one of #{collection}, but got #{value}"
|
109
|
-
fail_assertion(msg) unless collection.include?(value)
|
110
|
-
end
|
111
|
-
|
112
|
-
def assert_matches(name, value, options)
|
113
|
-
matcher = options[:matches]
|
114
|
-
msg = "Expected #{name} to match #{matcher}, but #{value} does not"
|
115
|
-
fail_assertion(msg) unless matcher.match(value)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|