-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
237 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
require "bundler/gem_tasks" | ||
require "bundler/setup" | ||
Bundler::GemHelper.install_tasks | ||
|
||
require "rspec/core/rake_task" | ||
|
||
RSpec::Core::RakeTask.new(:spec) | ||
# Adds dummy:db tasks. | ||
load "spec/dummy/Rakefile" | ||
|
||
task default: :spec | ||
# Declares gem's own tasks. | ||
desc "Runs test suite." | ||
task default: %w(dummy:db:migrate) do | ||
system "bundle exec rspec spec" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,51 @@ | ||
require "active_record" | ||
require "rspec" | ||
|
||
module RSpec::SQLimit | ||
require_relative "sqlimit/counter" | ||
end | ||
module RSpec | ||
module SQLimit | ||
require_relative "sqlimit/counter" | ||
require_relative "sqlimit/reporter" | ||
end | ||
|
||
Matchers.define :exceed_query_limit do |expected, matcher = nil| | ||
def counter | ||
@counter ||= RSpec::SQLimit::Counter.new | ||
end | ||
|
||
def message(expected, matcher, negation = false) | ||
if matcher | ||
condition = negation ? "maximum" : "more than" | ||
restriction = " that match #{matcher}" | ||
suffix = " among others (see mark ->)" | ||
end | ||
|
||
reporter = RSpec::SQLimit::Reporter.new(counter, matcher) | ||
|
||
<<-MESSAGE.gsub(/ +\|/, "") | ||
|Expected to run #{condition} #{expected} queries#{restriction} | ||
|The following #{reporter.count} queries were invoked#{suffix}: | ||
|#{reporter.lines.join("\n")} | ||
MESSAGE | ||
end | ||
|
||
match do |block| | ||
counter.count(&block) | ||
RSpec::SQLimit::Reporter.new(counter, matcher).count > expected | ||
end | ||
|
||
match_when_negated do |block| | ||
counter.count(&block) | ||
RSpec::SQLimit::Reporter.new(counter, matcher).count <= expected | ||
end | ||
|
||
failure_message do |_| | ||
message(expected, matcher) | ||
end | ||
|
||
failure_message_when_negated do |_| | ||
message(expected, matcher, true) | ||
end | ||
|
||
RSpec::Matchers.define :exceed_query_limit do | ||
match do |block| | ||
supports_block_expectations | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
module RSpec::SQLimit | ||
class Counter | ||
attr_reader :queries | ||
|
||
def initialize | ||
@queries = [] | ||
end | ||
|
||
# FIXME add mutex to ensure thread-safety | ||
def count | ||
@queries = [] | ||
ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do | ||
yield | ||
end | ||
end | ||
|
||
private | ||
|
||
def callback | ||
@callback ||= lambda(_name, start, finish, _message_id, values) do | ||
return if %w(CACHE SCHEMA).include? values[:name] | ||
queries << { sql: values[:sql], duration: (finish - start) * 1_000 } | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
module RSpec::SQLimit | ||
class Reporter | ||
attr_reader :matcher | ||
|
||
def initialize(counter, matcher = nil) | ||
@counter = counter | ||
@matcher = matcher | ||
end | ||
|
||
def count | ||
return queries.count unless @matcher | ||
queries.count { |query| query[:sql] =~ @matcher } | ||
end | ||
|
||
def lines | ||
queries.map.with_index { |*args| line(*args) } | ||
end | ||
|
||
private | ||
|
||
def line(query, index) | ||
prefix = @matcher && query =~ @matcher ? "->" : " " | ||
"#{prefix} #{index}) #{query[:sql]} (#{query[:duration].round(3)} ms)" | ||
end | ||
|
||
def queries | ||
@queries ||= @counter.queries | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
require "active_record" | ||
require "bundler/setup" | ||
|
||
namespace :dummy do | ||
task :environment do | ||
require_relative "lib/dummy" | ||
end | ||
|
||
namespace :db do | ||
task load_config: :environment | ||
end | ||
|
||
load "active_record/railties/databases.rake" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class Post < ActiveRecord::Base | ||
belongs_to :user | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class User < ActiveRecord::Base | ||
has_many :posts | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
test: | ||
adapter: :sqlite3 | ||
database: spec/dummy/db/test.sqlite3 | ||
pool: 5 | ||
timeout: 5000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Dummy::Application.configure do |config| | ||
dummy = File.expand_path "../..", __FILE__ | ||
database_yml = File.join(dummy, "config/database.yml") | ||
|
||
config.database_configuration = YAML.load File.read(database_yml) | ||
config.db_dir = File.join(dummy, "db") | ||
config.env = :test | ||
config.migrations_paths = [File.join(dummy, "db/migrate")] | ||
config.root = dummy | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class CreateUsers < ActiveRecord::Migration | ||
def change | ||
create_table :users do |t| | ||
t.string :name, index: true | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class CreatePosts < ActiveRecord::Migration | ||
def change | ||
create_table :posts do |t| | ||
t.references :users | ||
t.string :title | ||
t.text :text | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# This file is auto-generated from the current state of the database. Instead | ||
# of editing this file, please use the migrations feature of Active Record to | ||
# incrementally modify your database, and then regenerate this schema definition. | ||
# | ||
# Note that this schema.rb definition is the authoritative source for your | ||
# database schema. If you need to create the application database on another | ||
# system, you should be using db:schema:load, not running all the migrations | ||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations | ||
# you'll amass, the slower it'll run and the greater likelihood for issues). | ||
# | ||
# It's strongly recommended that you check this file into your version control system. | ||
|
||
ActiveRecord::Schema.define(version: 20170211104823) do | ||
|
||
create_table "posts", force: :cascade do |t| | ||
t.integer "users_id" | ||
t.string "title" | ||
t.text "text" | ||
end | ||
|
||
create_table "users", force: :cascade do |t| | ||
t.string "name" | ||
t.index ["name"], name: "index_users_on_name" | ||
end | ||
|
||
end |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require "active_record" | ||
require "bundler/setup" | ||
|
||
module Dummy | ||
require_relative "dummy/application" | ||
require_relative "../config/environment" | ||
require_relative "../app/models/user.rb" | ||
require_relative "../app/models/post.rb" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
module Dummy | ||
class Application | ||
class << self | ||
# Configuration settings wrapper for the | ||
# <tt>ActiveRecord::Tasks::DatabaseTasks</tt>. | ||
# | ||
# Establishes AR connection after configuration. | ||
# | ||
def configure | ||
yield tasks | ||
base.configurations = tasks.database_configuration | ||
base.establish_connection(tasks.env) | ||
end | ||
|
||
private | ||
|
||
def base | ||
@base ||= ActiveRecord::Base | ||
end | ||
|
||
def tasks | ||
@tasks ||= ActiveRecord::Tasks::DatabaseTasks | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
require "pry" | ||
require "rspec-sqlimit" | ||
require "database_cleaner" | ||
|
||
require_relative "dummy/lib/dummy" | ||
|
||
DatabaseCleaner.strategy = :truncation | ||
|
||
RSpec.configure do |config| | ||
config.order = :random | ||
config.filter_run focus: true | ||
config.run_all_when_everything_filtered = true | ||
|
||
# Prepare the Test namespace for constants defined in specs | ||
config.after(:each) { DatabaseCleaner.clean } | ||
end |