From 1d1c8fe4ad10872bbbed29699fdda4106ca3be51 Mon Sep 17 00:00:00 2001 From: Alessandro Rodi Date: Wed, 6 Jul 2022 14:19:43 +0200 Subject: [PATCH] Disable negated matcher for rspec --- CHANGELOG.md | 2 ++ lib/cancan/matchers.rb | 11 +++++++++++ spec/cancan/matchers_spec.rb | 6 ++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98fb2e7d..e320fe3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Disable `expect(...).not_to be_able_to(:action_a, :action_b)` for multiple actions because it leads to ambiguity. ([@coorasse][]) + ## 3.4.0 * [#691](https://github.com/CanCanCommunity/cancancan/pull/691): Add two new subquery strategies: `joined_alias_exists_subquery`, `joined_alias_each_rule_as_exists_subquery`. ([@kaspernj][]) diff --git a/lib/cancan/matchers.rb b/lib/cancan/matchers.rb index ccc8e0b5..34c6cb39 100644 --- a/lib/cancan/matchers.rb +++ b/lib/cancan/matchers.rb @@ -23,6 +23,17 @@ end end + match_when_negated do |ability| + actions = args.first + if actions.is_a? Array + raise NotImplementedError, "`expect(...).not_to be_able_to(:action_a, :action_b)` is no longer supported.\n" \ + "This syntax leads to ambiguity and it has therefore been disabled.\n" \ + 'Please split into separate expectations.' + else + !ability.can?(*args) + end + end + # Check that RSpec is < 2.99 if !respond_to?(:failure_message) && respond_to?(:failure_message_for_should) alias_method :failure_message, :failure_message_for_should diff --git a/spec/cancan/matchers_spec.rb b/spec/cancan/matchers_spec.rb index 5990e1a4..fe0b1e14 100644 --- a/spec/cancan/matchers_spec.rb +++ b/spec/cancan/matchers_spec.rb @@ -46,13 +46,11 @@ end it 'delegates to can? with array of abilities with empty array' do - is_expected.not_to be_able_to([], 123) + expect { is_expected.not_to be_able_to([], 123) }.to raise_error(NotImplementedError) end it 'delegates to can? with array of abilities with only one eligible ability' do - is_expected.to receive(:can?).with(:read, 123) { true } - is_expected.to receive(:can?).with(:update, 123) { false } - is_expected.not_to be_able_to(%i[read update], 123) + expect { is_expected.not_to be_able_to(%i[read update], 123) }.to raise_error(NotImplementedError) end end end