searchlight 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTA2YmIzYjk0NDhkNjdlNTg5MWU3MWQzOWExOTg0Mzg0Y2VmYjhkYw==
5
+ data.tar.gz: !binary |-
6
+ N2I3MmFlOGEzMjFiODcyNjUxNzA1ZWUxZjg4YmY5OTk0OWZjZGNlOQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OWUxMjY2OGYxMjNmZGJiOTgyYjY3OGVkYzgxOWI4NTQ2ZmI2YzA2N2MwYTA4
10
+ NGQ3Y2FjYmM4MTRjZGU2OWY1YjQ3MDg3MmJjNDAxMzY1NWM2OTJjN2VlZDNh
11
+ MzY5YjIzZjE2MGRkYzVmZTMyMTI3ZmU3MzVkMTU0MTliZjVmNzI=
12
+ data.tar.gz: !binary |-
13
+ ODJjNGM2NmQzNWFjY2FlYjUwN2EzNGQwN2MzNjI2Njg4MjE2NWUxNzg3ZjJl
14
+ ZDk4NzcxYzUzNzE4NWQ3ODg5NGZmZmUwOGM0ODljOTE5MDRiYWIzMmMzMDJl
15
+ MTMzMWU2YmEwMWY3MjM2MzU1MjJlZTk0MDNlNjBmY2VjM2U5ZGQ=
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .rvmrc
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchlight.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Nathan Long
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # Searchlight
2
+
3
+ Searchlight helps you build searches from options via Ruby methods that you write.
4
+
5
+ Searchlight comes with ActiveRecord integration, but can call search methods on any ORM or object that allows chaining search methods.
6
+
7
+ [![Build Status](https://api.travis-ci.org/nathanl/searchlight.png?branch=master)](https://travis-ci.org/nathanl/searchlight)
8
+ [![Code Climate](https://codeclimate.com/github/nathanl/searchlight.png)](https://codeclimate.com/github/nathanl/searchlight)
9
+
10
+ ## Overview
11
+
12
+ The basic idea of Searchlight is to build a search by chaining method calls that you define. It calls methods on the object you specify, based on the options you pass.
13
+
14
+ For example, if you have a Searchlight search class called `FooSearch`, and you instantiate it like this:
15
+
16
+ ```ruby
17
+ foo_search = FooSearch(active: true, name: 'Jimmy', location_in: %w[NY LA]) # or params[:query]
18
+ ```
19
+
20
+ ... calling `results` will call the instance methods `search_active`, `search_name`, and `search_location_in`. (If you omit the `active` option, `search_active` won't be called.)
21
+
22
+ The `results` method will then return the return value of the last search method. If you're using ActiveRecord, this would be an `ActiveRecord::Relation`. You can then call `each` to loop through the results, `to_sql` to get the generated query, etc.
23
+
24
+ ## Usage
25
+
26
+ ### Search class
27
+
28
+ Here's an example search class that uses ActiveRecord.
29
+
30
+ ```ruby
31
+ # app/searches/account_search.rb
32
+ class AccountSearch < Searchlight::Search
33
+
34
+ # Defines the `search_target`
35
+ search_on Account
36
+
37
+ # The search options this class knows how to handle
38
+ searches :contract_id, :invoicing_status, :active
39
+
40
+ # If a `contract_id` option is given, this method will be called
41
+ def search_contract_id
42
+ search.where(contract_id: contract_id)
43
+ end
44
+
45
+ # If an `invoicing` option is given, this method will be called
46
+ def search_invoicing
47
+ case invoicing_status
48
+ when 'partial'
49
+ search.partially_invoiced
50
+ when 'complete'
51
+ search.completely_invoiced
52
+ when 'never'
53
+ search.uninvoiced
54
+ else
55
+ search
56
+ end
57
+ end
58
+
59
+ # If an `active` option is given, this method will be called
60
+ def search_active
61
+ search.where(status: active? ? 'active' : 'inactive')
62
+ end
63
+
64
+ end
65
+ ```
66
+
67
+ ### Controller
68
+
69
+ ```ruby
70
+ # app/controllers/accounts_controller.rb
71
+ class AccountsController
72
+
73
+ def search
74
+ @search = AccountSearch.new(params[:search])
75
+ end
76
+ ...
77
+ ```
78
+
79
+ ### View
80
+ ```ruby
81
+ # app/views/accounts/index.html.haml
82
+ ...
83
+ = form_for(search, url: '#') do |f|
84
+ %fieldset
85
+ = f.label :contract_id, "Contract"
86
+ = f.select :contract_id, available_contracts_collection
87
+
88
+ %fieldset
89
+ = f.label :invoicing_status, "Invoicing Status"
90
+ = f.select :invoicing_status, invoice_statuses_collection
91
+
92
+ %fieldset
93
+ = f.label :active, "Active?"
94
+ = f.select :active, [['Active', true], ['Inactive', false], ['Either', nil]]
95
+ ```
96
+
97
+ ## Installation
98
+
99
+ Add this line to your application's Gemfile:
100
+
101
+ gem 'searchlight'
102
+
103
+ And then execute:
104
+
105
+ $ bundle
106
+
107
+ Or install it yourself as:
108
+
109
+ $ gem install searchlight
110
+
111
+ ## Contributing
112
+
113
+ 1. Fork it
114
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
115
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
116
+ 4. Push to the branch (`git push origin my-new-feature`)
117
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task "default" => "spec"
@@ -0,0 +1,26 @@
1
+ module Searchlight
2
+ module Adapters
3
+ module ActionView
4
+
5
+ module ClassMethods
6
+
7
+ def model_name
8
+ ActiveModel::Name.new(self, nil, 'query')
9
+ end
10
+
11
+ end
12
+
13
+ module InstanceMethods
14
+
15
+ def to_key
16
+ []
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+
25
+ Searchlight::Search.send(:include, Searchlight::Adapters::ActionView::InstanceMethods)
26
+ Searchlight::Search.extend(Searchlight::Adapters::ActionView::ClassMethods)
@@ -0,0 +1,30 @@
1
+ module Searchlight
2
+ module Adapters
3
+ module ActiveRecord
4
+
5
+ def search_on(target)
6
+ super
7
+ extend Search if target.is_a?(::ActiveRecord::Base)
8
+ end
9
+
10
+ module Search
11
+ def searches(*attribute_names)
12
+ super
13
+
14
+ include_new_module "SearchlightActiveRecordSearches" do
15
+ attribute_names.each do |attribute_name|
16
+ define_method("search_#{attribute_name}") do
17
+ search.where(attribute_name => public_send(attribute_name))
18
+ end
19
+ end
20
+ end
21
+
22
+ attribute_names.each { |attribute_name| method_added("search_#{attribute_name}") }
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+
30
+ Searchlight::Search.extend(Searchlight::Adapters::ActiveRecord)
@@ -0,0 +1,30 @@
1
+ module Searchlight
2
+ module DSL
3
+
4
+ def search_on(target)
5
+ @search_target = target
6
+ end
7
+
8
+ def searches(*attribute_names)
9
+ include_new_module "SearchlightAccessors" do
10
+ attr_accessor *attribute_names
11
+
12
+ # define boolean accessors
13
+ attribute_names.each do |attribute_name|
14
+ define_method("#{attribute_name}?") do
15
+ # Treat 0 (eg, from checkboxes) as false
16
+ !['0', 'false', ''].include?(public_send(attribute_name).to_s.strip)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # So that we can allow calling `super` in submodules and the base class.
25
+ def include_new_module(module_name, &content)
26
+ include Named::Module.new(module_name, &content)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,49 @@
1
+ require 'set'
2
+
3
+ module Searchlight
4
+ class Search
5
+ extend DSL
6
+
7
+ def self.search_target
8
+ defined?(@search_target) ? @search_target : superclass.search_target
9
+ end
10
+
11
+ def self.search_methods
12
+ defined?(@search_methods) ? @search_methods : superclass.search_methods
13
+ end
14
+
15
+ def self.method_added(name)
16
+ @search_methods ||= Set.new
17
+ search_methods << name.to_s if name.to_s.start_with?('search_')
18
+ end
19
+
20
+ def initialize(options = {})
21
+ options.each { |key, value| public_send("#{key}=", value) }
22
+ end
23
+
24
+ def search
25
+ @search ||= self.class.search_target
26
+ end
27
+
28
+ def results
29
+ @results ||= run
30
+ end
31
+
32
+ protected
33
+
34
+ attr_writer :search
35
+
36
+ private
37
+
38
+ def run
39
+ self.class.search_methods.each do |method|
40
+ option_value = public_send(method.sub(/\Asearch_/, ''))
41
+ unless option_value.nil? || option_value.to_s.strip == ''
42
+ self.search = public_send(method)
43
+ end
44
+ end
45
+ search
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Searchlight
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'named'
2
+ require 'searchlight/version'
3
+
4
+ module Searchlight
5
+ end
6
+
7
+ require 'searchlight/dsl'
8
+ require 'searchlight/search'
9
+ require 'searchlight/adapters/active_record' if defined?(::ActiveRecord)
10
+ require 'searchlight/adapters/action_view' if defined?(::ActionView)
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'searchlight/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "searchlight"
8
+ spec.version = Searchlight::VERSION
9
+ spec.authors = ["Nathan Long", "Adam Hunter"]
10
+ spec.email = ["nathanmlong@gmail.com", "adamhunter@me.com"]
11
+ spec.description = %q{Searchlight helps you build searches from options via Ruby methods that you write.}
12
+ spec.summary = %q{Searchlight helps you build searches from options via Ruby methods that you write.}
13
+ spec.homepage = "https://github.com/nathanl/searchlight"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "named", "~> 1.0"
22
+
23
+ spec.add_development_dependency "rspec", "~> 2.13"
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rails", ">= 3"
27
+ spec.add_development_dependency "capybara", "~> 2.0"
28
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Searchlight::Adapters::ActionView', type: :feature, adapter: true do
4
+
5
+ before :all do
6
+ require 'searchlight/adapters/action_view'
7
+ require 'action_view'
8
+ end
9
+
10
+ let(:view) { ::ActionView::Base.new }
11
+ let(:search) { AccountSearch.new(paid_amount: 15) }
12
+
13
+ before :each do
14
+ view.stub(:protect_against_forgery?).and_return(false)
15
+ end
16
+
17
+ it "it can be used to build a form" do
18
+ form = view.form_for(search, url: '#') do |f|
19
+ f.text_field(:paid_amount)
20
+ end
21
+
22
+ expect(form).to have_selector("form input[name='query[paid_amount]'][value='15']")
23
+ end
24
+
25
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Searchlight::Adapters::ActiveRecord', adapter: true do
4
+
5
+ before :all do
6
+ require 'searchlight/adapters/active_record'
7
+ require 'active_record'
8
+ end
9
+
10
+ let(:search_class) { Named::Class.new('SearchClass', Searchlight::Search) { search_on MockActiveRecord } }
11
+ let(:search_instance) { search_class.new(elephants: 'yes, please') }
12
+
13
+ before :each do
14
+ search_class.searches :elephants
15
+ end
16
+
17
+ it "adds search methods to the search class" do
18
+ expect(search_class.new).to respond_to(:search_elephants)
19
+ end
20
+
21
+ it "adds search_elephants to the search_methods array" do
22
+ expect(search_class.search_methods).to include('search_elephants')
23
+ end
24
+
25
+ it "defines search methods that call where on the search target" do
26
+ search_instance.results
27
+ expect(search_instance.search.called_methods).to eq([:where])
28
+ end
29
+
30
+ end
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+
3
+ describe Searchlight::Search do
4
+
5
+ let(:search_class) { Named::Class.new('SearchClass', described_class) }
6
+ let(:options) { Hash.new }
7
+ let(:search) { search_class.new(options) }
8
+
9
+ describe "initializing" do
10
+
11
+ let(:options) { {beak_color: 'mauve'} }
12
+
13
+ it "mass-assigns provided options" do
14
+ search_class.searches :beak_color
15
+ expect(search.beak_color).to eq('mauve')
16
+ end
17
+
18
+ end
19
+
20
+ describe "search_on" do
21
+
22
+ let(:search_target) { "Bobby Fischer" }
23
+
24
+ before :each do
25
+ search_class.search_on search_target
26
+ end
27
+
28
+ it "makes the object accessible via `search_target`" do
29
+ expect(search_class.search_target).to eq(search_target)
30
+ end
31
+
32
+ it "makes the search target available to its children" do
33
+ expect(SpiffyAccountSearch.search_target).to be(MockModel)
34
+ end
35
+
36
+ it "allows the children to set their own search target" do
37
+ klass = Class.new(SpiffyAccountSearch) { search_on Array }
38
+ expect(klass.search_target).to be(Array)
39
+ expect(SpiffyAccountSearch.search_target).to be(MockModel)
40
+ end
41
+
42
+ end
43
+
44
+ describe "search_methods" do
45
+
46
+ let(:search_class) {
47
+ Named::Class.new('SearchClass', described_class) do
48
+ def search_bees
49
+ end
50
+
51
+ def search_bats
52
+ end
53
+
54
+ def search_bees
55
+ end
56
+ end
57
+ }
58
+
59
+ it "keeps a unique list of the search methods" do
60
+ expect(search_class.search_methods).to eq(Set.new(['search_bees', 'search_bats']))
61
+ end
62
+
63
+ end
64
+
65
+ describe "search options" do
66
+
67
+ describe "accessors" do
68
+
69
+ before :each do
70
+ search_class.searches :foo
71
+ end
72
+
73
+ it "includes a SearchlightAccessors module" do
74
+ accessors_module = search_class.ancestors.detect {|a| a.name == 'SearchlightAccessors' }
75
+ expect(accessors_module).to be_a(Named::Module)
76
+ end
77
+
78
+ it "adds a getter" do
79
+ expect(search).to respond_to(:foo)
80
+ end
81
+
82
+ it "adds a setter" do
83
+ expect(search).to respond_to(:foo=)
84
+ end
85
+
86
+ it "adds a boolean accessor" do
87
+ expect(search).to respond_to(:foo?)
88
+ end
89
+
90
+ end
91
+
92
+ describe "accessing search options as booleans" do
93
+
94
+ let(:options) { {fishies: fishies} }
95
+
96
+ before :each do
97
+ search_class.searches :fishies
98
+ end
99
+
100
+ {
101
+ 0 => false,
102
+ '0' => false,
103
+ '' => false,
104
+ ' ' => false,
105
+ nil => false,
106
+ 'false' => false,
107
+ 1 => true,
108
+ '1' => true,
109
+ 15 => true,
110
+ 'true' => true,
111
+ 'pie' => true
112
+ }.each do |input, output|
113
+
114
+ describe input.inspect do
115
+
116
+ let(:fishies) { input }
117
+
118
+ it "becomes boolean #{output}" do
119
+ expect(search.fishies?).to eq(output)
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
130
+ describe "search" do
131
+
132
+ let(:search) { AccountSearch.new }
133
+
134
+ it "is initialized with the search_target" do
135
+ expect(search.search).to eq(MockModel)
136
+ end
137
+
138
+ end
139
+
140
+ describe "results" do
141
+
142
+ let(:search) { AccountSearch.new(paid_amount: 50, business_name: "Rod's Meat Shack") }
143
+
144
+ it "builds a search by calling all of the methods that had values to search" do
145
+ search.results
146
+ expect(search.search.called_methods).to eq(2.times.map { :where })
147
+ end
148
+
149
+ it "returns the search" do
150
+ expect(search.results).to eq(search.search)
151
+ end
152
+
153
+ it "only runs the search once" do
154
+ search.should_receive(:run).once.and_call_original
155
+ 2.times { search.results }
156
+ end
157
+
158
+ end
159
+
160
+ describe "run" do
161
+
162
+ let(:search_class) {
163
+ Named::Class.new('TinyBs', described_class) do
164
+ search_on Object
165
+ searches :bits, :bats, :bots
166
+
167
+ def search_bits; end
168
+ def search_bats; end
169
+ def search_bots; end
170
+
171
+ end
172
+ }
173
+
174
+ let(:search_instance) { search_class.new(bits: ' ', bats: nil, bots: false) }
175
+
176
+ it "only runs search methods that have real values to search on" do
177
+ search_instance.should_not_receive(:search_bits)
178
+ search_instance.should_not_receive(:search_bats)
179
+ search_instance.should_receive(:search_bots)
180
+ search_instance.send(:run)
181
+ end
182
+
183
+ end
184
+
185
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Searchlight do
4
+
5
+ it "is a module" do
6
+ expect(Searchlight).to be_a(Module)
7
+ end
8
+
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'capybara/rspec'
2
+ require 'searchlight'
3
+ $LOAD_PATH << '.'
4
+ require 'support/mock_model'
5
+ require 'support/account_search'
6
+ require 'support/spiffy_account_search'
7
+
8
+ RSpec.configure do |config|
9
+ config.treat_symbols_as_metadata_keys_with_true_values = true
10
+ config.run_all_when_everything_filtered = true
11
+ config.filter_run :focus
12
+
13
+ # Run specs in random order to surface order dependencies. If you find an
14
+ # order dependency and want to debug it, you can fix the order by providing
15
+ # the seed, which is printed after each run.
16
+ # --seed 1234
17
+ config.order = 'random'
18
+ end
@@ -0,0 +1,23 @@
1
+ class AccountSearch < Searchlight::Search
2
+
3
+ search_on MockModel
4
+
5
+ searches :paid_amount, :business_name, :balance, :active
6
+
7
+ def search_paid_amount
8
+ search.where('amount > ?', paid_amount)
9
+ end
10
+
11
+ def search_business_name
12
+ search.where(business_name: business_name)
13
+ end
14
+
15
+ def search_balance
16
+ search.where("owed - amount > ?", balance)
17
+ end
18
+
19
+ def search_active
20
+ search.where(active: active?)
21
+ end
22
+
23
+ end
@@ -0,0 +1,27 @@
1
+ class MockModel
2
+
3
+ def self.method_missing(method, *args, &block)
4
+ MockRelation.new(method)
5
+ end
6
+
7
+ end
8
+
9
+ class MockActiveRecord < MockModel
10
+
11
+ def self.is_a?(thing)
12
+ thing == ActiveRecord::Base ? true : super
13
+ end
14
+
15
+ end
16
+
17
+ class MockRelation
18
+ attr_reader :called_methods
19
+
20
+ def initialize(called_method)
21
+ @called_methods = [called_method]
22
+ end
23
+
24
+ def method_missing(method, *args, &block)
25
+ tap { called_methods << method }
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ class SpiffyAccountSearch < AccountSearch
2
+
3
+ searches :spiffiness
4
+
5
+ def search_spiffiness
6
+ search.where(spiffiness: spiffiness)
7
+ end
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: searchlight
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nathan Long
8
+ - Adam Hunter
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: named
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '2.13'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '2.13'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '1.3'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '1.3'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '3'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '3'
84
+ - !ruby/object:Gem::Dependency
85
+ name: capybara
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ version: '2.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: '2.0'
98
+ description: Searchlight helps you build searches from options via Ruby methods that
99
+ you write.
100
+ email:
101
+ - nathanmlong@gmail.com
102
+ - adamhunter@me.com
103
+ executables: []
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - .gitignore
108
+ - .rspec
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - lib/searchlight.rb
114
+ - lib/searchlight/adapters/action_view.rb
115
+ - lib/searchlight/adapters/active_record.rb
116
+ - lib/searchlight/dsl.rb
117
+ - lib/searchlight/search.rb
118
+ - lib/searchlight/version.rb
119
+ - searchlight.gemspec
120
+ - spec/searchlight/adapters/action_view_spec.rb
121
+ - spec/searchlight/adapters/active_record_spec.rb
122
+ - spec/searchlight/search_spec.rb
123
+ - spec/searchlight_spec.rb
124
+ - spec/spec_helper.rb
125
+ - spec/support/account_search.rb
126
+ - spec/support/mock_model.rb
127
+ - spec/support/spiffy_account_search.rb
128
+ homepage: https://github.com/nathanl/searchlight
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.0.3
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Searchlight helps you build searches from options via Ruby methods that you
152
+ write.
153
+ test_files:
154
+ - spec/searchlight/adapters/action_view_spec.rb
155
+ - spec/searchlight/adapters/active_record_spec.rb
156
+ - spec/searchlight/search_spec.rb
157
+ - spec/searchlight_spec.rb
158
+ - spec/spec_helper.rb
159
+ - spec/support/account_search.rb
160
+ - spec/support/mock_model.rb
161
+ - spec/support/spiffy_account_search.rb