Releases: palkan/n_plus_one_control
0.7.0
Changes
- Ruby 2.7+ is required.
Features
- Added ability to specify the exact number of expected queries when using constant matchers.
For RSpec, you can add the .exactly
modifier:
expect { get :index }.to perform_constant_number_of_queries.exactly(1)
For Minitest, you can provide the expected number of queries as the first argument:
assert_perform_constant_number_of_queries(0, **options) do
get :index
end
v0.6.2
Fixes
-
ignore
feature was documented, but not implemented.
Now, you actually can set up your ownignore
pattern and it will be respected. -
Matchers propagate inner failures.
In order to test the behavior along with performance, you always could do something likeexpect do expect(query).to match(expected_result) end.to perform_constant_number_of_queries
Previously, in case if the inner expectation was not met, you would receive a very weird error. Now, you will get an actual error message of the inner expectation.
0.6.0
Features
- Added linear number of queries assertion.
Now you can set up an expectation of linear growth of the number of queries. It can be helpful when you already have N+1 and for some reason you cannot fix it right now, so you want to prevent it from growing. Example:
# RSpec
context "when has linear query", :n_plus_one do
populate { |n| create_list(:post, n) }
specify do
expect { Post.find_each { |p| p.user.name } }
.to perform_linear_number_of_queries(slope: 1)
end
end
# Minitest
def test_no_n_plus_one_error
populate = ->(n) { create_list(:post, n) }
assert_perform_linear_number_of_queries(slope: 1, populate: populate) do
Post.find_each { |p| p.user.name }
end
end
Fixes
- Added support for backticks in table names.
If your rails application uses backticks around table names in database queries, they will be correctly processed in verbose mode.
0.5.0
Changes
This release stops support for EOL Ruby versions. Now Ruby 2.5+ is required.
Features
- Added location to SQLs in verbose mode.
Now you can see which location in your source code triggered a query.
To change the number of backtrace lines to display (1 by default), use NPLUSONE_BACKTRACE
env var or
NPlusOneControl.backtrace_length
configuration parameter.
- Added ability to truncate queries in verbose mode.
You can specify the length limit for displayed queries via NPLUSONE_TRUNCATE
env var or NPlusOneControl.truncate_query_size
configuration parameter.
- Added ability to pass default filter via
NPLUSONE_FILTER
env var.
It's useful when you want to narrow verbose output only to the affected table(-s) and remove all the other queries.
For example, NPLUSONE_FILTER=users bundle exec rake test
.
0.4.1
Features
A failure message now also includes information about the database tables which have unmatched number of queries:
Expected to make the same number of queries, but got:
3 for N=2
4 for N=3
Unmatched query numbers by tables:
users (SELECT): 2 != 3
Also, verbose output is moved to the end (so, we can clearly see the numbers first).
Fixes
Passing populate
parameter to assert_perform_constant_number_of_queries
never worked. Now it works 🙂
0.4.0
Added current_scale
functionality
From now on, instead of using populate
block and (re)creating records on each execution of block being tested, the user can add parameters to the block depending on current_scale
. This method will return the current scale factor.
RSpec usage:
context "N+1", :n_plus_one do
specify do
expect { get :index, params: { limit: current_scale } }.to perform_constant_number_of_queries
end
end
Minitest usage:
def test_no_n_plus_one
assert_perform_constant_number_of_queries do
get :index, params: { limit: current_scale }
end
end
0.3.0
Features
- Added
warmup
functionality.
The warmup
block is invoked once before the experiments. It aims to solve the caching-like problems, e.g. when your memoize something in your controller instance or use other caching techniques.
Without warming up the fist run might show more queries than the following runs.
RSpec usage:
context "N + 1", :n_plus_one do
populate { |n| create_list :post, n }
# cache something that must be cached
warmup { get :index }
specify do
expect { get :index }.to perform_constant_number_of_queries
end
end
Minitest usage:
def populate(n)
create_list(:post, n)
end
def warmup
get :index
end
def test_no_n_plus_one_error
assert_perform_constant_number_of_queries do
get :index
end
end
# or with params
def test_no_n_plus_one
populate = ->(n) { create_list(:post, n) }
warmup = -> { get :index }
assert_perform_constant_number_of_queries population: populate, warmup: warmup do
get :index
end
end