search_lingo 2.0.0.pre2 → 2.0.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48dc212ce20b6ca6d502ad3776598375e9aadf5aba67448a0db0833ff9ae9b22
4
- data.tar.gz: 9110f9d208a47032ded854d4541eb2d212359599f8b6ddc13bdb6add5c4ee6ab
3
+ metadata.gz: 3a72223dbfe08f7309fc060e7bb30afd3e4941810ba9f52fcf50340d6573db74
4
+ data.tar.gz: c560f79d14abbf7daa9a570ac0594184afb0aca4f69acf66ed86f4af15c6d5be
5
5
  SHA512:
6
- metadata.gz: a9bfec6dad76471dedab609b8eef445c3b61bfb3eaded66d362849a1f42192de117485b7a9c4157aa8277a7a8a34df5f9c9f1aa15997d001751c92a3259172fe
7
- data.tar.gz: 38a894d13baec1cb47a68bf805243fe238355dcf65cc35effae2d5c3d304082883fa73e60de07340d2f29c74ad15e89b5b1ca6d20235a63bfd6cd545b07d67af
6
+ metadata.gz: 343f682d46cf9ea34fafa75499790e0e0a0474e812c8c00cce81fe75b3f2f1b5de66975d0e2d975f4eca8e12deeedf2e9b927ebcce425fef9871d5405b686023
7
+ data.tar.gz: 725c8dca98f88dd630475c200e7b2ecb0347cb191df5d10e7e0dae9ac0c3e3d815e2830966f2bf18c6bd5448842a78a946a5ec6e60a6e58acaf83aa586adc6d8
data/.rubocop.yml ADDED
@@ -0,0 +1,14 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3.0
3
+ Layout/AlignParameters:
4
+ Enabled: false
5
+ Metrics/AbcSize:
6
+ Max: 25
7
+ Style/AndOr:
8
+ EnforcedStyle: conditionals
9
+ Style/TrailingCommaInArrayLiteral:
10
+ Enabled: false
11
+ Style/TrailingCommaInHashLiteral:
12
+ Enabled: false
13
+ Style/NumericPredicate:
14
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.3.7
3
4
  - 2.4.4
4
5
  - 2.5.1
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in search_lingo.gemspec
data/Rakefile CHANGED
@@ -1,9 +1,15 @@
1
- require "bundler/gem_tasks"
1
+ # frozen-string-literal: true
2
+
3
+ require 'bundler/gem_tasks'
2
4
  require 'rake/testtask'
3
5
 
4
6
  Rake::TestTask.new do |t|
5
7
  t.libs << 'test'
6
- t.pattern = 'test/**/test_*.rb'
8
+ t.pattern = 'test/**/*_test.rb'
7
9
  end
8
10
 
9
11
  task default: :test
12
+
13
+ task :rubocop do
14
+ system 'rubocop'
15
+ end
data/bin/console CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen-string-literal: true
2
3
 
3
- require "bundler/setup"
4
- require "search_lingo"
4
+ require 'bundler/setup'
5
+ require 'search_lingo'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
8
9
 
9
10
  # (If you use this, don't forget to add pry to your Gemfile!)
10
- require "pry"
11
+ require 'pry'
11
12
  Pry.start
12
13
 
13
14
  # require "irb"
data/examples/complex.rb CHANGED
@@ -1,9 +1,19 @@
1
+ # frozen-string-literal: true
2
+
1
3
  class Job < ActiveRecord::Base # :nodoc:
2
- # Assume this model has attributes: :id, :date, :name
4
+ # Attributes:
5
+ # :id
6
+ # :date
7
+ # :name
3
8
  end
4
9
 
5
10
  class Receipt < ActiveRecord::Base # :nodoc:
6
- # Assume this model has attributes: :id, :check_no, :check_date, :post_date, :amount
11
+ # Attributes:
12
+ # :id
13
+ # :check_no
14
+ # :check_date
15
+ # :post_date
16
+ # :amount
7
17
  end
8
18
 
9
19
  module Parsers # :nodoc:
@@ -13,7 +23,7 @@ module Parsers # :nodoc:
13
23
  end
14
24
 
15
25
  def call(token, chain)
16
- token.match /\Aid:\s*([[:digit:]]+)\z/ do |m|
26
+ token.match(/\Aid:\s*([[:digit:]]+)\z/) do |m|
17
27
  chain.where @table => { id: m[1] }
18
28
  end
19
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'sequel'
2
4
  require 'sqlite3'
3
5
 
@@ -17,12 +19,13 @@ require 'sqlite3'
17
19
 
18
20
  class CategoryParser # :nodoc:
19
21
  def call(token, chain)
20
- if token.modifier == 'cat'
21
- # This is kind of broken. The categories table will be joined once each
22
- # time this parser matches a token.
23
- chain.join(:categories, id: :category_id)
24
- .where Sequel.qualify('categories', 'name') => token.term
25
- end
22
+ return nil unless token.modifier == 'cat'
23
+
24
+ # This is not an ideal example. Sequel will join the categories table for
25
+ # each token that matches. I'm ignoring the problem since this is only an
26
+ # example.
27
+ category_name = Sequel.qualify :categories, :name
28
+ chain.join(:categories, id: :category_id).where category_name => token.term
26
29
  end
27
30
  end
28
31
 
@@ -57,7 +60,8 @@ class TaskSearch < SearchLingo::AbstractSearch # :nodoc:
57
60
  date = Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}"
58
61
  chain.where due_date: date
59
62
  rescue ArgumentError
60
- # Date.parse raised an ArgumentError
63
+ # Fail if Date.parse raises an ArgumentError
64
+ nil
61
65
  end
62
66
  end
63
67
  end
data/lib/search_lingo.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'search_lingo/version'
2
4
  require 'search_lingo/abstract_search'
3
5
  require 'search_lingo/parsers'
@@ -1,6 +1,37 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'search_lingo/tokenizer'
2
4
 
3
5
  module SearchLingo
6
+ ##
7
+ # AbstractSearch is an abstract implementation from which search classes
8
+ # should inherit.
9
+ #
10
+ # Search classes are instantiated with a query string and a default scope on
11
+ # which to perform the search.
12
+ #
13
+ # Child classes must implement the #default_parse instance method, and they
14
+ # may optionally register one or more parsers.
15
+ #
16
+ # class MySearch < SearchLingo::AbstractSearch
17
+ # def default_parse(token, chain)
18
+ # chain.where attribute: token.term
19
+ # end
20
+ # end
21
+ #
22
+ # class MyOtherSearch < SearchLingo::AbstractSearch
23
+ # parser SearchLingo::Parsers::DateParser.new Job.arel_table[:date]
24
+ #
25
+ # parser do |token, chain|
26
+ # token.match(/\Aid: [[:space:]]* (?<id>[[:digit:]]+)\z/x) do |m|
27
+ # chain.where id: m[:id]
28
+ # end
29
+ # end
30
+ #
31
+ # def default_parse(token, chain)
32
+ # chain.where Job.arel_table[:name].matches "%#{token.term}%"
33
+ # end
34
+ # end
4
35
  class AbstractSearch
5
36
  attr_reader :query, :scope
6
37
 
@@ -8,7 +39,9 @@ module SearchLingo
8
39
  # Instantiates a new search object. +query+ is the string that is to be
9
40
  # parsed and compiled into an actual query. If +query+ is falsey, an empty
10
41
  # string will be used. +scope+ is the object to which the compiled query
11
- # should be sent, e.g., an +ActiveRecord+ model.
42
+ # should be sent, e.g., an +ActiveRecord::Relation+.
43
+ #
44
+ # MySearchClass.new 'foo bar: baz "froz quux"', Task.all
12
45
  def initialize(query, scope)
13
46
  @query = query || ''
14
47
  @scope = scope
@@ -46,6 +79,7 @@ module SearchLingo
46
79
  unless block_given? ^ parser.respond_to?(:call)
47
80
  raise ArgumentError, 'parse must be called with callable OR block'
48
81
  end
82
+
49
83
  parsers << (parser || block)
50
84
  end
51
85
 
@@ -115,7 +149,7 @@ module SearchLingo
115
149
  # This is a skeletal implementation that raises +NotImplementedError+.
116
150
  # Child classes should provide their own implementation. At a minimum, that
117
151
  # implementation should return +chain+. (Doing so would ignore +token+.)
118
- def default_parse(token, chain)
152
+ def default_parse(_token, _chain)
119
153
  raise NotImplementedError,
120
154
  "#default_parse must be implemented by #{self.class}"
121
155
  end
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module SearchLingo
2
4
  ##
3
5
  # Pattern for matching modifiers within a token.
@@ -1 +1,3 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'search_lingo/parsers/date_parser'
@@ -1,36 +1,57 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'search_lingo/parsers/mdy'
2
4
 
3
5
  module SearchLingo
4
6
  module Parsers # :nodoc:
7
+ ##
8
+ # DateParser is an example parser which handles dates that adhere to the
9
+ # MDY format used in the US. It uses `SearchLingo::Parsers::MDY.parse` to
10
+ # parse the date. It handles simple dates as well as closed and open-ended
11
+ # date ranges.
12
+ #
13
+ # Examples of single dates are 7/14, 7/14/17, and 7/14/2017.
14
+ # Examples of closed date ranges are 1/1-6/30 and 7/1/16-6/30/18.
15
+ # Examples of open date ranges are -6/30 and 7/1/17-.
5
16
  class DateParser
6
17
  include MDY
7
18
 
19
+ attr_reader :column, :prefix, :append
20
+
8
21
  ##
9
22
  # Instantiates a new DateParser object.
10
23
  #
11
24
  # The required argument +column+ should be an Arel attribute.
12
25
  #
13
26
  # If present, the optional argument +modifier+ will be used as the
14
- # operator which precedes the date term.
27
+ # token operator which precedes the date term.
28
+ #
29
+ # If a block is provided, it will be used to append additional methods to
30
+ # the filter chain. (This is useful for static methods that must be
31
+ # appended to the filter chain independent of the content of the token,
32
+ # for example, if you need to join another table.)
15
33
  #
16
- # DateParser.new Booking.arel_table[:date]
17
- # DateParser.new Contract.arel_table[:date], modifier: 'contract'
18
- def initialize(column, modifier: nil)
34
+ # DateParser.new Model.arel_table[:date]
35
+ # DateParser.new Model.arel_table[:date], modifier: 'contract'
36
+ # DateParser.new Model.arel_table[:date] do |chain|
37
+ # chain.joins(:relation)
38
+ # end
39
+ def initialize(column, modifier: nil, &block)
19
40
  @column = column
20
- @prefix = %r{#{modifier}:[[:space:]]*} if modifier
41
+ @prefix = /#{modifier}:[[:space:]]*/ if modifier
42
+ @append = if block_given?
43
+ block
44
+ else
45
+ ->(chain) { chain }
46
+ end
21
47
  end
22
48
 
23
- attr_reader :column, :prefix
24
-
25
49
  ##
26
- # Attempts to parse the token as a date, closed date range, or open date
27
- # range.
28
- #
29
- # Examples of single dates are 7/14, 7/14/17, and 7/14/2017.
30
- # Examples of closed date ranges are 1/1-6/30 and 7/1/16-6/30/18.
31
- # Examples of open date ranges are -6/30 and 7/1/17-.
50
+ # Attempts to parse +token+ as a single date, closed date range, or open
51
+ # date range. If parsing succeeds, the parser sends #where to +chain+
52
+ # with the appropriate Arel node and returns the result.
32
53
  def call(token, chain)
33
- catch :stop do
54
+ catch :halt do
34
55
  parse_single_date token, chain
35
56
  parse_date_range token, chain
36
57
  parse_lte_date token, chain
@@ -39,38 +60,40 @@ module SearchLingo
39
60
  end
40
61
 
41
62
  def inspect # :nodoc:
42
- '#<%s:0x%x @prefix=%s @column=%s>' %
43
- [self.class, object_id << 1, prefix.inspect, column.inspect]
63
+ format '#<%<cls>s @prefix=%<prefix>s @column=%<column>s>',
64
+ cls: self.class,
65
+ prefix: prefix.inspect,
66
+ column: column.inspect
44
67
  end
45
68
 
46
69
  private
47
70
 
48
- def parse_single_date(token, chain)
71
+ def parse_single_date(token, chain) # :nodoc:
49
72
  token.match(/\A#{prefix}(?<date>#{US_DATE})\z/) do |m|
50
73
  date = parse(m[:date]) or return nil
51
- throw :stop, chain.where(column.eq(date))
74
+ throw :halt, append.call(chain).where(column.eq(date))
52
75
  end
53
76
  end
54
77
 
55
- def parse_date_range(token, chain)
78
+ def parse_date_range(token, chain) # :nodoc:
56
79
  token.match(/\A#{prefix}(?<min>#{US_DATE})-(?<max>#{US_DATE})\z/) do |m|
57
80
  min = parse(m[:min]) or return nil
58
81
  max = parse(m[:max], relative_to: min.next_year) or return nil
59
- throw :stop, chain.where(column.in(min..max))
82
+ throw :halt, append.call(chain).where(column.in(min..max))
60
83
  end
61
84
  end
62
85
 
63
- def parse_lte_date(token, chain)
86
+ def parse_lte_date(token, chain) # :nodoc:
64
87
  token.match(/\A#{prefix}-(?<date>#{US_DATE})\z/) do |m|
65
88
  date = parse(m[:date]) or return nil
66
- throw :stop, chain.where(column.lteq(date))
89
+ throw :halt, append.call(chain).where(column.lteq(date))
67
90
  end
68
91
  end
69
92
 
70
- def parse_gte_date(token, chain)
93
+ def parse_gte_date(token, chain) # :nodoc:
71
94
  token.match(/\A#{prefix}(?<date>#{US_DATE})-\z/) do |m|
72
95
  date = parse(m[:date]) or return nil
73
- throw :stop, chain.where(column.gteq(date))
96
+ throw :halt, append.call(chain).where(column.gteq(date))
74
97
  end
75
98
  end
76
99
  end
@@ -1,7 +1,12 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  module SearchLingo
4
6
  module Parsers # :nodoc:
7
+ ##
8
+ # MDY provides a parser for dates that adhere to the MDY format used in the
9
+ # US.
5
10
  module MDY
6
11
  ##
7
12
  # Pattern for matching US-formatted date strings.
@@ -22,25 +27,30 @@ module SearchLingo
22
27
  # defaults to today's date.
23
28
  #
24
29
  # Available as both a class method and an instance method.
30
+ # rubocop:disable Metrics/MethodLength
25
31
  def parse(term, relative_to: Date.today)
26
- term.match /\A#{US_DATE}\z/ do |m|
32
+ term.match(/\A#{US_DATE}\z/) do |m|
27
33
  return Date.parse "#{m[:y]}/#{m[:m]}/#{m[:d]}" if m[:y]
28
34
 
29
35
  ref = relative_to
30
- day = Integer(m[:d])
31
- month = Integer(m[:m])
36
+ month = Integer m[:m]
37
+ day = Integer m[:d]
32
38
  year = if month < ref.month || month == ref.month && day <= ref.day
33
39
  ref.year
34
40
  else
35
41
  ref.year - 1
36
42
  end
37
-
38
43
  Date.new year, month, day
39
44
  end
40
45
  rescue ArgumentError
46
+ # Fail if Date.parse or Date.new raise ArgumentError.
47
+ nil
41
48
  end
49
+ # rubocop:enable Metrics/MethodLength
42
50
 
51
+ # rubocop:disable Style/AccessModifierDeclarations:
43
52
  module_function :parse
53
+ # rubocop:enable Style/AccessModifierDeclarations:
44
54
  end
45
55
  end
46
56
  end
@@ -1,7 +1,22 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'delegate'
2
4
  require 'search_lingo/constants'
3
5
 
4
6
  module SearchLingo
7
+ ##
8
+ # Single token from a query string. A token consists of a term an an optional
9
+ # modifier. The term may be a word or multiple words contained within double
10
+ # quotes. The modifier is one or more alphanumeric characters. The modifier
11
+ # and term and separated by a colon followed by zero or more whitespace
12
+ # characters.
13
+ #
14
+ # The following are examples of tokens:
15
+ #
16
+ # Token.new('foo')
17
+ # Token.new('"foo bar"')
18
+ # Token.new('foo: bar')
19
+ # Token.new('foo: "bar baz"')
5
20
  class Token < DelegateClass(String)
6
21
  ##
7
22
  # Pattern for decomposing a token into a modifier and a term.
@@ -17,7 +32,7 @@ module SearchLingo
17
32
  self[STRUCTURE, 1]
18
33
  end
19
34
 
20
- alias_method :operator, :modifier
35
+ alias operator modifier
21
36
 
22
37
  ##
23
38
  # Returns the term portion of the token. If the term is wrapped in quotes,
@@ -36,12 +51,15 @@ module SearchLingo
36
51
  # Token.new('foo: bar').compound? # => true
37
52
  # Token.new('bar').compound? # => false
38
53
  def compound?
39
- !!modifier
54
+ !modifier.nil? && !modifier.empty?
40
55
  end
41
56
 
42
57
  def inspect # :nodoc:
43
- '#<%s String(%s) modifier=%s term=%s>' %
44
- [self.class, super, modifier.inspect, term.inspect]
58
+ format '#<%<cls>s String(%<str>s) modifier=%<mod>s term=%<term>s>',
59
+ cls: self.class,
60
+ str: super,
61
+ mod: modifier.inspect,
62
+ term: term.inspect
45
63
  end
46
64
  end
47
65
  end
@@ -1,9 +1,17 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'forwardable'
2
4
  require 'strscan'
3
5
  require 'search_lingo/constants'
4
6
  require 'search_lingo/token'
5
7
 
6
8
  module SearchLingo
9
+ ##
10
+ # Tokenizer breaks down a query string into individual tokens.
11
+ #
12
+ # Tokenizer.new 'foo'
13
+ # Tokenizer.foo 'foo "bar baz"'
14
+ # Tokenizer.foo 'foo "bar baz" froz: quux'
7
15
  class Tokenizer
8
16
  include Enumerable
9
17
  extend Forwardable
@@ -30,9 +38,7 @@ module SearchLingo
30
38
  def each
31
39
  return to_enum(__callee__) unless block_given?
32
40
 
33
- until scanner.eos?
34
- yield self.next
35
- end
41
+ yield self.next until scanner.eos?
36
42
  end
37
43
 
38
44
  ##
@@ -42,6 +48,7 @@ module SearchLingo
42
48
  scanner.skip DELIMITER
43
49
  token = scanner.scan COMPOUND_TOKEN
44
50
  raise StopIteration unless token
51
+
45
52
  Token.new token
46
53
  end
47
54
 
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module SearchLingo
2
- VERSION = '2.0.0.pre2'
4
+ VERSION = '2.0.0.pre3'
3
5
  end
data/search_lingo.gemspec CHANGED
@@ -1,34 +1,43 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen-string-literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'search_lingo/version'
5
6
 
7
+ # rubocop:disable Metrics/BlockLength
6
8
  Gem::Specification.new do |spec|
7
- spec.name = "search_lingo"
9
+ spec.name = 'search_lingo'
8
10
  spec.version = SearchLingo::VERSION
9
- spec.authors = ["John Parker"]
10
- spec.email = ["jparker@urgetopunt.com"]
11
+ spec.authors = ['John Parker']
12
+ spec.email = ['jparker@urgetopunt.com']
11
13
 
12
- spec.summary = %q{Framework for defining and parsing search queries.}
13
- spec.description = %q{SearchLingo is a simple framework for defining simple query languages and translating them into application-specific queries.}
14
- spec.homepage = "https://github.com/jparker/search_lingo"
15
- spec.license = "MIT"
14
+ spec.summary = 'Framework for defining and parsing search queries.'
15
+ spec.description = <<~DESCRIPTION
16
+ SearchLingo is a simple framework for defining simple query languages and
17
+ translating them into application-specific queries.
18
+ DESCRIPTION
19
+ spec.homepage = 'https://github.com/jparker/search_lingo'
20
+ spec.license = 'MIT'
16
21
 
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f|
23
+ f.match(%r{^(test|spec|features)/})
24
+ }
25
+ spec.bindir = 'exe'
19
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
27
+ spec.require_paths = ['lib']
21
28
 
22
29
  spec.rdoc_options += ['-x', 'examples/', '-x', 'test/']
23
30
 
24
- spec.required_ruby_version = '>= 2.1'
31
+ spec.required_ruby_version = '>= 2.3'
25
32
 
26
- spec.add_development_dependency "bundler", "~> 1.9"
27
- spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency 'bundler', '~> 1.9'
28
34
  spec.add_development_dependency 'minitest'
29
35
  spec.add_development_dependency 'minitest-focus'
30
36
  spec.add_development_dependency 'mocha'
31
37
  spec.add_development_dependency 'pry'
38
+ spec.add_development_dependency 'rake', '~> 10.0'
39
+ spec.add_development_dependency 'rubocop'
32
40
  spec.add_development_dependency 'sequel', '~> 5.0'
33
41
  spec.add_development_dependency 'sqlite3'
34
42
  end
43
+ # rubocop:enable Metrics/BlockLength
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_lingo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre2
4
+ version: 2.0.0.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Parker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-02 00:00:00.000000000 Z
11
+ date: 2018-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,21 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.9'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
42
+ name: minitest-focus
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest-focus
56
+ name: mocha
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: mocha
70
+ name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,21 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: pry
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -122,8 +136,9 @@ dependencies:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
- description: SearchLingo is a simple framework for defining simple query languages
126
- and translating them into application-specific queries.
139
+ description: |
140
+ SearchLingo is a simple framework for defining simple query languages and
141
+ translating them into application-specific queries.
127
142
  email:
128
143
  - jparker@urgetopunt.com
129
144
  executables: []
@@ -131,6 +146,7 @@ extensions: []
131
146
  extra_rdoc_files: []
132
147
  files:
133
148
  - ".gitignore"
149
+ - ".rubocop.yml"
134
150
  - ".travis.yml"
135
151
  - Gemfile
136
152
  - LICENSE.txt
@@ -166,7 +182,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
182
  requirements:
167
183
  - - ">="
168
184
  - !ruby/object:Gem::Version
169
- version: '2.1'
185
+ version: '2.3'
170
186
  required_rubygems_version: !ruby/object:Gem::Requirement
171
187
  requirements:
172
188
  - - ">"