rspec-sqlimit 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 475c6503c3977cff0ade02d623b23dfe2465b94f
4
+ data.tar.gz: 2d9f1030c97a6eb4d156d6a25ee38e46c44456ee
5
+ SHA512:
6
+ metadata.gz: c687ef9cb2d62c639cd924c90e6ee61417ddfe041e28f13c142b45e9ea35305d8d0f125c125c9d5cd6354dc937a0f9b8d3ab85414ddaaf79c1b3d0ff7a934b0b
7
+ data.tar.gz: 57a9ac1ed2e7a67f37def16516becfc1b38dfd403eccfe389f2e0b32498e446906f8d1ca8767823f8e3950892ed29a7385adc4d01c3251ecfda522ebe5772fb3
@@ -0,0 +1,18 @@
1
+ ---
2
+ engines:
3
+ bundler-audit:
4
+ enabled: true
5
+ duplication:
6
+ enabled: true
7
+ config:
8
+ languages:
9
+ - ruby
10
+ fixme:
11
+ enabled: true
12
+ rubocop:
13
+ enabled: true
14
+ ratings:
15
+ paths:
16
+ - "**.rb"
17
+ exclude_paths:
18
+ - spec/
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
@@ -0,0 +1,32 @@
1
+ ---
2
+ AllCops:
3
+ DisplayCopNames: true
4
+ DisplayStyleGuide: true
5
+ StyleGuideCopsOnly: true
6
+ TargetRubyVersion: 2.3
7
+ Exclude:
8
+ - spec/dummy/db/schema.rb
9
+
10
+ Metrics/ParameterLists:
11
+ Max: 5
12
+
13
+ Style/Alias:
14
+ Enabled: false
15
+
16
+ Style/ClassAndModuleChildren:
17
+ EnforcedStyle: compact
18
+
19
+ Style/FileName:
20
+ Enabled: false
21
+
22
+ Style/FrozenStringLiteralComment:
23
+ Enabled: false
24
+
25
+ Style/ModuleFunction:
26
+ Enabled: false
27
+
28
+ Style/StringLiterals:
29
+ EnforcedStyle: double_quotes
30
+
31
+ Style/StringLiteralsInInterpolation:
32
+ EnforcedStyle: double_quotes
@@ -0,0 +1,13 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ script:
6
+ - bundle exec rspec
7
+ rvm:
8
+ - 2.3.0
9
+ - ruby-head
10
+ before_install: gem install bundler
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tram-form.gemspec
4
+ gemspec
5
+
6
+ group :test, :development do
7
+ gem "pry"
8
+ gem "pry-byebug"
9
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Andrew Kozin (nepalez), Evil Martians
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,126 @@
1
+ # Test-Driven way of fighting N + 1 queries
2
+
3
+ RSpec matcher to control number of SQL queries executed by a block of code.
4
+
5
+ It wraps [the answer at Stack Overflow][stack-answer] by [Ryan Bigg][ryan-bigg], which based on Active Support [Notification][notification] and [Instrumentation][instrumentation] mechanisms.
6
+
7
+ [![Gem Version][gem-badger]][gem]
8
+ [![Build Status][travis-badger]][travis]
9
+ [![Dependency Status][gemnasium-badger]][gemnasium]
10
+ [![Code Climate][codeclimate-badger]][codeclimate]
11
+
12
+ <a href="https://evilmartians.com/">
13
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
14
+
15
+ ## Installation
16
+
17
+ ```ruby
18
+ # Gemfile
19
+ gem "rspec-sqlimit"
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ The gem defines matcher `exceed_query_limit` that takes maximum number of SQL requests to be made inside the block.
25
+
26
+ ```ruby
27
+ require "rspec-sqlimit"
28
+
29
+ RSpec.describe "N+1 safety" do
30
+ it "doesn't send unnecessary requests to db" do
31
+ expect { User.create }.not_to exceed_query_limit(1)
32
+ end
33
+ end
34
+ ```
35
+
36
+ The above specification fails with the following description:
37
+
38
+ ```
39
+ Failure/Error: expect { User.create }.not_to exceed_query_limit(1)
40
+
41
+ Expected to run maximum 1 queries
42
+ The following 3 queries were invoked:
43
+ 1) begin transaction (0.045 ms)
44
+ 2) INSERT INTO "users" DEFAULT VALUES (0.19 ms)
45
+ 3) commit transaction (148.935 ms)
46
+ ```
47
+
48
+ You can restrict the matcher using regex:
49
+
50
+ ```ruby
51
+ require "rspec-sqlimit"
52
+
53
+ RSpec.describe "N+1 safety" do
54
+ it "doesn't send unnecessary requests to db" do
55
+ expect { User.create }.not_to exceed_query_limit(1).with(/^INSERT/)
56
+ end
57
+ end
58
+ ```
59
+
60
+ This time test passes.
61
+
62
+ When a specification with a restriction fails, you'll see an error as follows:
63
+
64
+ ```ruby
65
+ require "rspec-sqlimit"
66
+
67
+ RSpec.describe "N+1 safety" do
68
+ it "doesn't send unnecessary requests to db" do
69
+ expect { User.create }.not_to exceed_query_limit(1).with(/^INSERT/)
70
+ end
71
+ end
72
+ ```
73
+
74
+ ```
75
+ Failure/Error: expect { User.create }.not_to exceed_query_limit(0).with(/INSERT/)
76
+
77
+ Expected to run maximum 0 queries that match (?-mix:INSERT)
78
+ The following 1 queries were invoked among others (see mark ->):
79
+ 1) begin transaction (0.072 ms)
80
+ -> 2) INSERT INTO "users" DEFAULT VALUES (0.368 ms)
81
+ 3) commit transaction (147.559 ms)
82
+ ```
83
+
84
+ ## Further Development
85
+
86
+ For now the gem uses unbinded Active Record queries in error descriptions. For example, when your query contains arguments, the error message will look like
87
+
88
+ ```ruby
89
+ require "rspec-sqlimit"
90
+
91
+ RSpec.describe "N+1 safety" do
92
+ it "doesn't send unnecessary requests to db" do
93
+ expect { User.create(name: "Joe") }.not_to exceed_query_limit(1)
94
+ end
95
+ end
96
+ ```
97
+
98
+ ```
99
+ Failure/Error: expect { User.create }.not_to exceed_query_limit(0).with(/INSERT/)
100
+
101
+ Expected to run maximum 0 queries that match (?-mix:INSERT)
102
+ The following 1 queries were invoked among others (see mark ->):
103
+ 1) begin transaction (0.072 ms)
104
+ -> 2) INSERT INTO "users" ("name") VALUES (?) (0.368 ms)
105
+ 3) commit transaction (147.559 ms)
106
+ ```
107
+
108
+ This is because [Active Record instrumentation hook][hook] keeps a query and bindings separately (under `:sql` and `:binds` keys). So the challenge is **to bind arguments to the query** in the report to make a debugging a bit simpler.
109
+
110
+ ## License
111
+
112
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
113
+
114
+ [codeclimate-badger]: https://img.shields.io/codeclimate/github/nepalez/rspec-sqlimit.svg?style=flat
115
+ [codeclimate]: https://codeclimate.com/github/nepalez/rspec-sqlimit
116
+ [gem-badger]: https://img.shields.io/gem/v/rspec-sqlimit.svg?style=flat
117
+ [gem]: https://rubygems.org/gems/rspec-sqlimit
118
+ [gemnasium-badger]: https://img.shields.io/gemnasium/nepalez/rspec-sqlimit.svg?style=flat
119
+ [gemnasium]: https://gemnasium.com/nepalez/rspec-sqlimit
120
+ [travis-badger]: https://img.shields.io/travis/nepalez/rspec-sqlimit/master.svg?style=flat
121
+ [travis]: https://travis-ci.org/nepalez/rspec-sqlimit
122
+ [stack-answer]: http://stackoverflow.com/a/5492207/1869912
123
+ [ryan-bigg]: http://ryanbigg.com/
124
+ [notification]: http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html
125
+ [instrumentation]: http://guides.rubyonrails.org/active_support_instrumentation.html
126
+ [hook]: http://guides.rubyonrails.org/active_support_instrumentation.html#sql-active-record
@@ -0,0 +1,13 @@
1
+ require "bundler/setup"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+
6
+ # Adds dummy:db tasks.
7
+ load "spec/dummy/Rakefile"
8
+
9
+ # Declares gem's own tasks.
10
+ desc "Runs test suite."
11
+ task default: %w(dummy:db:migrate) do
12
+ system "bundle exec rspec spec"
13
+ end
@@ -0,0 +1 @@
1
+ require_relative "rspec/sqlimit"
@@ -0,0 +1,47 @@
1
+ require "active_support/notifications"
2
+ require "active_record"
3
+ require "rspec"
4
+
5
+ module RSpec
6
+ module SQLimit
7
+ require_relative "sqlimit/counter"
8
+ require_relative "sqlimit/reporter"
9
+ end
10
+
11
+ Matchers.define :exceed_query_limit do |expected|
12
+ chain :with do |matcher|
13
+ @matcher = matcher
14
+ end
15
+
16
+ match do |block|
17
+ @counter ||= RSpec::SQLimit::Counter[@matcher, block]
18
+ @counter.count > expected
19
+ end
20
+
21
+ match_when_negated do |block|
22
+ @counter ||= RSpec::SQLimit::Counter[@matcher, block]
23
+ @counter.count <= expected
24
+ end
25
+
26
+ failure_message do |_|
27
+ message(expected, @counter)
28
+ end
29
+
30
+ failure_message_when_negated do |_|
31
+ message(expected, @counter, true)
32
+ end
33
+
34
+ supports_block_expectations
35
+
36
+ def message(expected, counter, negation = false)
37
+ reporter = RSpec::SQLimit::Reporter.new(counter)
38
+ condition = negation ? "maximum" : "more than"
39
+ restriction = " that match #{reporter.matcher}" if reporter.matcher
40
+
41
+ <<-MESSAGE.gsub(/ +\|/, "")
42
+ |Expected to run #{condition} #{expected} queries#{restriction}
43
+ |#{reporter.call}
44
+ MESSAGE
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ module RSpec::SQLimit
2
+ class Counter
3
+ attr_reader :queries, :matcher
4
+
5
+ def self.[](*args)
6
+ new(*args).tap(&:call)
7
+ end
8
+
9
+ def initialize(matcher, block)
10
+ @queries = []
11
+ @matcher = matcher
12
+ @block = block
13
+ @mutex = Mutex.new
14
+ end
15
+
16
+ def call
17
+ @mutex.synchronize do
18
+ @queries = []
19
+ ActiveSupport::Notifications.subscribed callback, "sql.active_record" do
20
+ @block.call
21
+ end
22
+ end
23
+ end
24
+
25
+ def count
26
+ matcher ? queries.count { |query| query[:sql] =~ matcher } : queries.count
27
+ end
28
+
29
+ private
30
+
31
+ def callback
32
+ @callback ||= lambda do |_name, start, finish, _message_id, values|
33
+ return if %w(CACHE SCHEMA).include? values[:name]
34
+ queries << { sql: values[:sql], duration: (finish - start) * 1_000 }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ module RSpec::SQLimit
2
+ class Reporter
3
+ attr_reader :matcher
4
+
5
+ def initialize(counter)
6
+ @counter = counter
7
+ @count = counter.count
8
+ @queries = counter.queries
9
+ @matcher = counter.matcher
10
+ end
11
+
12
+ def call
13
+ suffix = " among others (see mark ->)" if @matcher
14
+
15
+ return "No queries were invoked" if @queries.empty?
16
+
17
+ <<-MESSAGE.gsub(/ +\|/, "")
18
+ |The following #{@count} queries were invoked#{suffix}:
19
+ |#{lines.join("\n")}
20
+ MESSAGE
21
+ end
22
+
23
+ private
24
+
25
+ def lines
26
+ @queries.map.with_index { |*args| line(*args) }
27
+ end
28
+
29
+ def line(query, index)
30
+ prefix = (matcher && query[:sql] =~ matcher) ? "->" : " "
31
+ "#{prefix} #{index + 1}) #{query[:sql]} (#{query[:duration].round(3)} ms)"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |gem|
2
+ gem.name = "rspec-sqlimit"
3
+ gem.version = "0.0.1"
4
+ gem.author = "Andrew Kozin (nepalez)"
5
+ gem.email = "andrew.kozin@gmail.com"
6
+ gem.homepage = "https://github.com/nepalez/rspec-sqlimit"
7
+ gem.summary = "RSpec matcher to control SQL queries made by block of code"
8
+ gem.license = "MIT"
9
+
10
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
11
+ gem.test_files = gem.files.grep(/^spec/)
12
+ gem.extra_rdoc_files = Dir["README.md", "LICENSE", "CHANGELOG.md"]
13
+
14
+ gem.required_ruby_version = ">= 2.3"
15
+
16
+ gem.add_runtime_dependency "rails", "> 4.0", "< 6.0"
17
+ gem.add_runtime_dependency "rspec", "~> 3.0"
18
+
19
+ gem.add_development_dependency "rspec", "~> 3.0"
20
+ gem.add_development_dependency "rake", "> 10.0"
21
+ gem.add_development_dependency "sqlite3", "~> 1.3"
22
+ gem.add_development_dependency "database_cleaner", "~> 1.5"
23
+ gem.add_development_dependency "rubocop", "~> 0.44"
24
+ end
@@ -0,0 +1,14 @@
1
+ require "active_record"
2
+ require "bundler/setup"
3
+
4
+ namespace :dummy do
5
+ task :environment do
6
+ require_relative "lib/dummy"
7
+ end
8
+
9
+ namespace :db do
10
+ task load_config: :environment
11
+ end
12
+
13
+ load "active_record/railties/databases.rake"
14
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :posts
3
+ end
@@ -0,0 +1,6 @@
1
+ ---
2
+ test:
3
+ adapter: :sqlite3
4
+ database: spec/dummy/db/test.sqlite3
5
+ pool: 5
6
+ timeout: 5000
@@ -0,0 +1,10 @@
1
+ Dummy::Application.configure do |config|
2
+ dummy = File.expand_path "../..", __FILE__
3
+ database_yml = File.join(dummy, "config/database.yml")
4
+
5
+ config.database_configuration = YAML.load File.read(database_yml)
6
+ config.db_dir = File.join(dummy, "db")
7
+ config.env = :test
8
+ config.migrations_paths = [File.join(dummy, "db/migrate")]
9
+ config.root = dummy
10
+ end
@@ -0,0 +1,5 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended that you check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(version: 20170211104800) do
14
+
15
+ create_table "users", force: :cascade do |t|
16
+ end
17
+
18
+ end
@@ -0,0 +1,8 @@
1
+ require "active_record"
2
+ require "bundler/setup"
3
+
4
+ module Dummy
5
+ require_relative "dummy/application"
6
+ require_relative "../config/environment"
7
+ require_relative "../app/models/user.rb"
8
+ end
@@ -0,0 +1,26 @@
1
+ module Dummy
2
+ class Application
3
+ class << self
4
+ # Configuration settings wrapper for the
5
+ # <tt>ActiveRecord::Tasks::DatabaseTasks</tt>.
6
+ #
7
+ # Establishes AR connection after configuration.
8
+ #
9
+ def configure
10
+ yield tasks
11
+ base.configurations = tasks.database_configuration
12
+ base.establish_connection(tasks.env)
13
+ end
14
+
15
+ private
16
+
17
+ def base
18
+ @base ||= ActiveRecord::Base
19
+ end
20
+
21
+ def tasks
22
+ @tasks ||= ActiveRecord::Tasks::DatabaseTasks
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe "exceed_query_limit" do
4
+ context "without restrictions" do
5
+ it "works when no queries are made" do
6
+ expect { User.new }.not_to exceed_query_limit(0)
7
+ end
8
+
9
+ it "works when actual number of queries is below the limit" do
10
+ expect { User.create }.not_to exceed_query_limit(3)
11
+ end
12
+
13
+ it "works when actual number of queries exceeds the limit" do
14
+ expect { User.create }.to exceed_query_limit(2)
15
+ end
16
+ end
17
+
18
+ context "with a restriction" do
19
+ it "works when no queries are made" do
20
+ expect { User.new }.not_to exceed_query_limit(0).with(/INSERT/)
21
+ end
22
+
23
+ it "works when actual number of queries is below the limit" do
24
+ expect { User.create }.not_to exceed_query_limit(1).with(/INSERT/)
25
+ end
26
+
27
+ it "works when actual number of queries exceeds the limit" do
28
+ expect { User.create id: 3 }.to exceed_query_limit(0).with(/INSERT/)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ require "pry"
2
+ require "rspec-sqlimit"
3
+ require "database_cleaner"
4
+
5
+ require_relative "dummy/lib/dummy"
6
+
7
+ DatabaseCleaner.strategy = :truncation
8
+
9
+ RSpec.configure do |config|
10
+ config.order = :random
11
+ config.filter_run focus: true
12
+ config.run_all_when_everything_filtered = true
13
+
14
+ # Prepare the Test namespace for constants defined in specs
15
+ config.after(:each) { DatabaseCleaner.clean }
16
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-sqlimit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kozin (nepalez)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '6.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: sqlite3
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.3'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.3'
89
+ - !ruby/object:Gem::Dependency
90
+ name: database_cleaner
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.5'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.5'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.44'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.44'
117
+ description:
118
+ email: andrew.kozin@gmail.com
119
+ executables: []
120
+ extensions: []
121
+ extra_rdoc_files:
122
+ - README.md
123
+ files:
124
+ - ".codeclimate.yml"
125
+ - ".gitignore"
126
+ - ".rspec"
127
+ - ".rubocop.yml"
128
+ - ".travis.yml"
129
+ - Gemfile
130
+ - LICENSE.txt
131
+ - README.md
132
+ - Rakefile
133
+ - lib/rspec-sqlimit.rb
134
+ - lib/rspec/sqlimit.rb
135
+ - lib/rspec/sqlimit/counter.rb
136
+ - lib/rspec/sqlimit/reporter.rb
137
+ - rspec-sqlimit.gemspec
138
+ - spec/dummy/Rakefile
139
+ - spec/dummy/app/models/user.rb
140
+ - spec/dummy/config/database.yml
141
+ - spec/dummy/config/environment.rb
142
+ - spec/dummy/db/migrate/20170211104800_create_users.rb
143
+ - spec/dummy/db/schema.rb
144
+ - spec/dummy/db/test.sqlite3
145
+ - spec/dummy/lib/dummy.rb
146
+ - spec/dummy/lib/dummy/application.rb
147
+ - spec/rspec/sqlimit_spec.rb
148
+ - spec/spec_helper.rb
149
+ homepage: https://github.com/nepalez/rspec-sqlimit
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '2.3'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.5.2
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: RSpec matcher to control SQL queries made by block of code
173
+ test_files:
174
+ - spec/dummy/Rakefile
175
+ - spec/dummy/app/models/user.rb
176
+ - spec/dummy/config/database.yml
177
+ - spec/dummy/config/environment.rb
178
+ - spec/dummy/db/migrate/20170211104800_create_users.rb
179
+ - spec/dummy/db/schema.rb
180
+ - spec/dummy/db/test.sqlite3
181
+ - spec/dummy/lib/dummy.rb
182
+ - spec/dummy/lib/dummy/application.rb
183
+ - spec/rspec/sqlimit_spec.rb
184
+ - spec/spec_helper.rb