Permalink
Commits on Jan 11, 2016
  1. Prepare NEWS before release

    [ci skip]
    mcmire committed Jan 11, 2016
  2. (feature): Add 'ignore_case_sensitivity' option

    Fixes #836
    also possibly #838
    ?
    
    The issue is that the existing functionality was either actively
    asserting case sensitivity or case insensitivity. This commit adds an
    option to not assert either.
    
    This allows handling of the scenario where the case of an attribute is
    changed at some point before being assigned on the model.
    dgmstuart committed with mcmire Nov 12, 2015
  3. Validate enum column is an integer in `define_enum_for`

    If your ActiveRecord model stores its `enum` data in a non-integer
    column, ActiveRecord will save the data without error. However, when you
    access the attribute on the record after saving, AR will look for the
    string to what it expects to be a list of numbers and return `nil`
    rather than the mapped value.
    
    This change adds a third criterion to the `define_enum_for` matcher,
    verifying that the underlying database column has a `sql_type` of
    `"integer"`.
    
    Fix #827.
    geoffharcourt committed with mcmire Nov 2, 2015
Commits on Jan 10, 2016
  1. allow_value: Correctly handle mix of good+bad vals

    Prior to 583be38, `allow_value` did not correctly fail when given a
    mixture of good and bad values. Assuming it was used in the positive,
    when given good values first followed by bad ones, then it failed as
    expected, but when given bad values first followed by good ones, then it
    passed when it wasn't supposed to.
    
    For example:
    
    ``` ruby
    class Post
      include ActiveModel::Model
      attr_accessor :color
      validates :color, format: { with: /\A#[a-f0-9]{6}\z/ }
    end
    
    describe Post do
      # fails, and should fail
      it { should allow_values('#FFFFFF', '#ffffff').for(:color) }
      # passes, but should fail
      it { should allow_values('#ffffff', '#FFFFFF').for(:color) }
    end
    ```
    
    The aforementioned commit fixed this issue because it made `allow_value`
    less stateful than it was. We didn't have tests to cover this behavior,
    though, so this commit adds them.
    mcmire committed Jan 10, 2016
  2. CreateTable supports all PG-specific columns even under Rails 4.0

    Successive versions of Rails provided explicit support for more column
    types such as `money` and `uuid`. However, the ability to create a
    Postgres table with one of these column type is really dependent on
    which Postgres version you're using, and not which Rails version you're
    using -- all you have to do is use `t.column` rather than e.g.,
    `t.money`, `t.uuid`, etc.
    mcmire committed Jan 10, 2016
  3. Add a test for numericality + money columns

    18b2859 and a0f1221 fixed the numericality matcher so that it no longer
    raises CouldNotSetAttributeError when used against numeric columns.
    Unfortunately, the issue still existed for money columns.
    
    This is fixed now, but we never explicitly tested for money columns, and
    this commit adds that test.
    mcmire committed Jan 10, 2016
  4. Update installation instructions for shoulda

    shoulda doesn't yet support shoulda-matchers 3.0, so have people install
    2.8.0 instead for now.
    
    [ci skip]
    mcmire committed Jan 10, 2016
Commits on Jan 7, 2016
  1. Numericality validation of virtual attributes

    Commit #18b2859d2522a4866c398b9a32ebc3de4ec79389 broke numericality
    validation of virtual attributes in ActiveRecord models. This commit
    added a `column_type` method that assumes if `columns_hash` is a thing
    then our attribute would be present within it. This is not true for
    virtual attributes and leads to:
    ```
         NoMethodError:
               undefined method `type' for nil:NilClass
             # /Users/bdmac/.gem/ruby/2.2.2/gems/shoulda-matchers-3.0.1/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb:442:in
             # `column_type'
    ```
    bdmac committed with mcmire Oct 28, 2015
  2. Always use doc formatter for RSpec by default

    Prior to this commit we only told RSpec to use the doc formatter if we
    were running one test file. When a test file is being run using Zeus,
    `unit_spec_helper` (and thus `spec_helper`) are loaded ahead of time.
    This means that from RSpec's perspective, no files are being run, and so
    the documentation formatter is not chosen, which means that the default
    progress reporter is used.
    
    This guard was added primarily to ensure that when tests are run on CI,
    the progress reporter is used instead of the documentation formatter.
    This happens anyway, though, because we pass that manually to RSpec
    within the Rakefile. So we don't need this guard.
    mcmire committed Jan 7, 2016
Commits on Jan 6, 2016
  1. Do not apply .railsrc

    mdeering committed with mcmire Oct 26, 2015
  2. Remove IneffectiveTestError

    Prior to this commit, the numericality matcher raised an
    IneffectiveTestError if used against a numeric column (unless other
    qualifiers were added). I had a misunderstanding of how the numericality
    validation works -- it turns out it doesn't work against the output of
    the attribute in question, it works against the input. So raising this
    exception is pointless and doesn't actually protect against anything.
    mcmire committed Jan 6, 2016
Commits on Jan 5, 2016
  1. Enable ignoring_interference_by_writer by default

    Forcing people to add ignoring_interference_by_writer for each and every
    case in which an attribute changes incoming values is pretty obnoxious
    on our part (for instance, when using the numericality matcher against
    an integer column + `only_integer`). So now, it's enabled by default.
    This effectively means that people should never get
    AtttributeChangedValueErrors again.
    mcmire committed Jan 5, 2016
  2. Add ignoring_interference_by_writer to all matchers

    `allow_value` matcher is, of course, concerned with setting values on a
    particular attribute on a particular record, and then checking that the
    record is valid after doing so. That comes with a caveat: if the
    attribute is overridden in such a way so that the same value going into
    the attribute isn't the same value coming out of it, then `allow_value`
    will balk -- it'll say, "I can't do that because that changes how I
    work."
    
    That's all well and good, but what the attribute intentionally changes
    incoming values? ActiveRecord's typecasting behavior, for instance,
    would trigger such an exception. What if the developer needs a way to
    get around this? This is where `ignoring_interference_by_writer` comes
    into play. You can tack it on to the end of the matcher, and you're free
    to go on your way.
    
    So, prior to this commit you could already apply it to `allow_value`,
    but now in this commit it also works on any other matcher.
    
    But, one little thing: sometimes using this qualifier isn't going to
    work. Perhaps you or something else actually *is* overriding the
    attribute to change incoming values in a specific way, and perhaps the
    value that comes out makes the record fail validation, and there's
    nothing you can do about it. So in this case, even if you're using
    `ignoring_interference_by_writer`, we want to inform you about what the
    attribute is doing -- what the input and output was. And so we do.
    mcmire committed Dec 31, 2015
  3. allow_value: Fix compatibility with enum columns

    When used against an attribute that's an enum, `allow_value` will raise
    an AttributeValueChangedError. This commit prevents that from happening.
    mcmire committed Dec 30, 2015
  4. Add ValidationMatcherScenario for use in tests

    Also add a helper method, `build_scenario_for_validation_matcher`, to
    all unit tests.
    
    Our plan is to slowly transition all of the tests to use this helper
    method, and that we we can get rid of the umpteen different ways we are
    building records across all of the tests.
    mcmire committed Dec 27, 2015
  5. Extract classes for defining models in tests

    The main driver behind this commit is to provide a programmatic way to
    define models in tests. We already have ways of doing this, of course,
    with `define_model` and `define_active_model_class`, but these methods
    are very low-level, and in writing tests we have historically made our
    own methods inside of test files to define full and complete models. So
    we have this common pattern of defining a model with a validation, and
    that's repeated across many different files.
    
    What we would like to do, right now, is extract some commonly used
    assertions to a shared example group. These assertions need to define
    models inside of the tests, but the issue is that sometimes the models
    are ActiveRecord models, and sometimes they are ActiveModel models, and
    when the shared example group is used within a test file, we need a way
    to choose the strategy we'd like to use at runtime. Since the way we
    currently define models is via methods, we can't really provide a
    strategy very easily. Also, if we need to customize how those models are
    defined (say, the attribute needs to be a has-many association instead
    of a normal attribute) then the methods only go so far in providing us
    that level of customization before things get really complicated.
    
    So, to help us with this, this commit takes the pattern of
    model-plus-validation previously mentioned and places it in multiple
    classes.
    
    Note that this is also a precursor to a later commit in which we
    introduce `ignoring_interference_by_writer` across the board. The way we
    will do this is by adding a shared example group that then uses these
    model creation classes internally to build objects instead of relying
    upon methods that the outer example group -- to which the shared example
    group is being mixed into -- provides.
    mcmire committed Dec 23, 2015
  6. uniqueness: Extract code to gen dummy values

    We need to use this in another part of the codebase: later, when we add
    ignoring_interference_by_writer to all matchers, we will need a way of
    overriding an attribute such that it produces another value that
    invalidates the test. Some tests require us to generate dummy values.
    mcmire committed Dec 27, 2015
Commits on Jan 4, 2016
  1. Dispel confusion around rails_helper in README

    [ci skip]
    mcmire committed Jan 4, 2016
Commits on Dec 31, 2015
  1. Update NEWS with latest changes

    [ci skip]
    mcmire committed Dec 31, 2015
  2. numericality: lazily assign submatchers/qualifiers

    The numericality matcher has two kinds of qualifiers: those that add new
    tests directly to the matcher, and those that change the behavior of
    those tests. For instance, consider `odd` and `strict`. Using `odd`
    instructs the matcher to verify not only that the attribute can only be
    set to a number, but that it must be set to an *odd* number. `strict`
    then instructs the `odd` matcher to make this verification with the
    assumption that a validation exception will be raised instead of the
    record producing a validation error.
    
    It follows, then, that these qualifiers are order-dependent. This test:
    
        should validate_numericality_of(:attr).strict.odd
    
    is actually a different test than:
    
        should validate_numericality_of(:attr).odd.strict
    
    Why? Because if `strict` is written before `odd`, then it doesn't have
    any submatchers to affect. But if it is written after, then it can see
    that `odd` is present and can apply itself to it.
    
    The fact that users have to remember to specify submatchers in a certain
    order is inconvenient, and we don't like it. So to fix this, this commit
    records whenever `strict` or other like qualifiers are used, but then
    waits to apply them to the other submatchers until #matches? is called
    (that is, when the matcher is run).
    mcmire committed Dec 26, 2015
  3. numericality: Do not run all submatchers

    This commit changes the numericality matcher so that when running
    submatchers, the matcher will stop on the first one that fails instead
    of running them all. Since all of the submatchers modify the same
    record, running all of them is actually bad since it could possibly make
    the failure message confusing (since the record will be in a mixed
    state).
    mcmire committed Dec 26, 2015
  4. numericality: Show msg from only 1st failing submatcher, not all

    If multiple submatchers that the numericality matcher creates fail, then
    all of their messages will be contained within the message for the
    numericality matcher itself. This ends up being too much information,
    especially since later, we're going to tack a note on the end of
    allow_value's message if we detect that an attribute has changed an
    incoming value. If we didn't just show the message for the first failing
    submatcher, then that note would be present for all of the submatchers,
    and that gets obnoxious fast.
    mcmire committed Dec 25, 2015
  5. Adjust message for AttributeDoesNotExistError

    Make it a little more clear that the attribute mentioned is on the
    model.
    mcmire committed Dec 31, 2015
  6. Remove tests for numericality submatchers

    All of these are tested indirectly through the tests for the
    numericality matcher itself. There are already plenty of tests to
    maintain, and so there's really no need to unit test these (not that
    they were truly "unit tested" to begin with).
    mcmire committed Dec 25, 2015
  7. Add 'it supports' as an alias for 'it behaves like'

    Oftentimes our shared example groups represent tests for qualifiers.
    It's more natural to say "it supports ignoring_interference_by_writer"
    instead of "it behaves like it supports
    ignoring_interference_by_writer".
    mcmire committed Dec 24, 2015
  8. Define attrs in a module when building AM models in tests

    When a developer builds an ActiveModel model and wants to override an
    attribute, she may do so using `super` to call the original method. For
    instance:
    
        def foo=(value)
          super(value.next)
        end
    
    as opposed to:
    
        def foo=(value)
          @foo = value.next
        end
    mcmire committed Dec 22, 2015
  9. Small tweaks to scripts that update gems

    The `update_gem_in_all_appraisals` script can do two things:
    
    * Update the given gem located in the Gemfile
    * Update the given gem located in Appraisals
    
    Currently, if the first step fails, then the second step does not run.
    With this commit, both will run regardless of their status.
    mcmire committed Dec 23, 2015
  10. Upgrade RSpec to v3.4

    v3.3 introduced a new feature: the ability to re-run failed specs. v3.4
    contains some other nifty features, such as code highlighting and
    compound failure messages.
    mcmire committed Dec 23, 2015
  11. allow_value: Inspect values more clearly

    Modify descriptions and failure messages for all matchers by way of
    allow_value and put small angle brackets around inspected values. This
    is to visually distinguish an inspected value from the rest of the text,
    and is especially noticeable for complex values such as an array that
    contains an object, particularly if the inspected version of the value
    wraps onto another line. It's a little easier to see:
    
        When attempting to set :attr on Example to ‹[#<Child id:
        nil>]›...
    
    rather than:
    
        When attempting to set :attr on Example to [#<Child id:
        nil>]...
    mcmire committed Dec 22, 2015
  12. confirmation: Refactor to use AttributeSetter

    When the confirmation matcher is setting the confirmation attribute, we
    want it to raise an exception if the model does not have that attribute,
    same as if it would raise an exception if the attribute under test did
    not exist.
    mcmire committed Dec 21, 2015
  13. Keep test Rails app directory clean

    All tests are run against a Rails app. The app is generated before each
    test, and one would think it gets removed after each test. For unit
    tests, this *does* happen before each test, but for acceptance tests, it
    does not get removed at all. This commit ensures that this happens, so
    that it is possible to run acceptance tests immediately after running
    unit tests.
    mcmire committed Dec 23, 2015