rspec-sqlimit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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