Skip to content

Releases: palkan/n_plus_one_control

0.7.0

17 Feb 16:59
Compare
Choose a tag to compare

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

26 Oct 18:03
e78e0dd
Compare
Choose a tag to compare

Fixes

  • ignore feature was documented, but not implemented.
    Now, you actually can set up your own ignore pattern and it will be respected.

  • Matchers propagate inner failures.
    In order to test the behavior along with performance, you always could do something like

    expect 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

27 Nov 14:28
eb3a851
Compare
Choose a tag to compare

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

07 Sep 15:53
Compare
Choose a tag to compare

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

04 Sep 11:51
Compare
Choose a tag to compare

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

21 Jul 10:42
Compare
Choose a tag to compare

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

19 Jun 17:03
Compare
Choose a tag to compare

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