search_lingo 2.0.0.pre2 → 2.0.0.pre3

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 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
  - - ">"