Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pretty print for policy rules #63

Merged
merged 2 commits into from
Mar 30, 2019
Merged

Add pretty print for policy rules #63

merged 2 commits into from
Mar 30, 2019

Conversation

palkan
Copy link
Owner

@palkan palkan commented Mar 30, 2019

This feature aims to:

  • provide better error messages for RSpec DSL
  • provide debug helpers for development.

NOTE: this functionality requires two additional gems to be available in the app:

Context

We usually describe policy rules using boolean expressions (e.g. A or (B and C), where each of A, B and C is a simple boolean expression or predicate method).

When dealing with complex policies it could be hard to figure out which predicate/check made policy to fail.

The Policy#pp(rule) method aims to help debug such situations.

Consider a (synthetic) example:

def feed?
  (admin? || allowed_to?(:access_feed?)) &&
    (user.name == "Jack" || user.name == "Kate")
end

Suppose that you want to debug this rule ("Why does it return false?").
You can drop a binding.pry (or binding.irb) right in the beginning of the method:

def feed?
  binding.pry
  #...
end

Now, run you code and trigger the breakpoint (i.e. run the method):

# now you can preview the execution of the rule using the `pp` method (defined on the policy instance)
pry> pp :feed?
MyPolicy#feed?
↳ (
    admin? #=> false
    OR
    allowed_to?(:access_feed?) #=> true
  )
  AND
  (
    user.name == "Jack" #=> false
    OR
    user.name == "Kate" #=> true
  )

# you can also check other rules or methods as well
pry> pp :admin?
MyPolicy#admin?
↳ user.admin? #=> false

This functionally is also used in RSpec DSL to format the message on failure:

describe_rule :manage? do
  succeed "when user is admin" do
    before { user.admin = true }
  end
end

Then if test fails you see the detailed error message:

$ bundle exec rspec ./spec/policies

1) UserPolucy#manage? when user is admin
Failure/Error:  ...

Expected to fail but succeed:
<UserPolicy#manage?: true>
↳ user.admin? #=> true
AND
!record.admin? #=> false

PR checklist:

  • Tests included
  • Documentation updated
  • Changelog entry added

@palkan palkan merged commit 85376ce into master Mar 30, 2019
@palkan palkan deleted the feat/pretty-print branch March 30, 2019 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant