Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

crispy

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

crispy

  • 0.4.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Crispy

Code Climate Test Coverage Build Status Gem Version

Test Spy for Any Object in Ruby.

Features

  • Test spy for ANY object by using prepend (Sorry, it runs by Ruby 2.0 or higher!)
  • Extremely flexible query for received messages with received_messages method.
    • By using Array and Enumerable's methods, you never have to remember the complex API and tons of the argument matchers in RSpec anymore!
  • Makes mocks obsolete so you don't have to be worried about where to put the expectations (i.e. before or after the subject method).

Installation

Add this line to your application's Gemfile:

gem 'crispy'

And then execute:

$ bundle

Or install it yourself as:

$ gem install crispy

Usage

Spy on an Object

>> require 'crispy'
>> include Crispy # import spy, spy_into and any other functions from Crispy namespace.

>> object = YourCoolClass.new
>> spy_into object # sneak into your object to spy.

# Use your object as usual.
>> object.your_cool_method 1, 2, 3
>> object.your_method_without_argument
>> object.your_lovely_method 'great', 'arguments'
>> object.your_lovely_method 'great', 'arguments', 'again'
>> object.your_finalizer 'resource to release'
Spy methods with no arguments

Call query methods through the spy object, instead of YourCoolClass's instance.

>> spy(object).received? :your_cool_method
=> true
>> spy(object).received? :your_method_without_argument
=> true
>> spy(object).received? :your_lovely_method
=> true
>> spy(object).received? :your_ugly_method
=> false
Spy methods with arguments

Each argument is compared by == method.

>> spy(object).received? :your_cool_method, 1, 2, 3
=> true
>> spy(object).received? :your_cool_method, 0, 0, 0
=> false
>> spy(object).received? :your_method_without_argument, :not, :given, :arguments
=> false
>> spy(object).received? :your_lovely_method, 'great', 'arguments'
=> true
>> spy(object).received? :your_ugly_method, 'of course', 'I gave no arguments'
=> false
Spy methods with arguments and a block

Sorry, I'm still thinking of the specification for that case.

Count method calls
>> spy(object).count_received :your_cool_method
=> 1
>> spy(object).count_received :your_cool_method, 1, 2, 3
=> 1
>> spy(object).count_received :your_cool_method, 0, 0, 0
=> 0
Get more detailed log

You can check arbitrary received methods with the familliar Array's (and of course including Enumerable's!) methods such as any?, all, first, [], index. Because spy(object).received_messages returns an array of CrispyReceivedMessage instances.
You don't have to remember the tons of matchers for received arguments any more!!

>>
  spy(object).received_messages.any? do|m|
    m.method_name == :your_cool_method && m.arguments.all? {|arg| arg.is_a? Integer }
  end
=> true

>> last_method_call = spy(object).received_messages.last
>>
  last_method_call.method_name == :your_finalizer &&
    last_method_call.arguments == ['resource to release']
=> true

Stub Methods of a Spy

>> spy(object).stub(:your_cool_method, 'Awesome!')
>> object.your_cool_method
=> "Awesome!"

>> spy(object).stub(your_lovely_method: 'I love this method!', your_finalizer: 'Finalized!')
>> object.your_lovely_method
=> "I love this method!"
>> object.your_finalizer
=> "Finalized!"

Of cource stubbed methods are spied as well.

>> spy(object).received? :your_cool_method
=> true

# `spy(object)` keeps its spied log of a method even after stubbing the method.
>> spy(object).count_received :your_lovely_method
=> 3

Spy on Instances of a Class

>> spy_into_instances(YourCoolClass)
>> instance1 = YourCoolClass.new
>> instance2 = YourCoolClass.new

>> instance1.your_cool_method 'and', 'args'
>> instance2.your_lovely_method
>> instance2.your_lovely_method 'again!'
>> instance1.your_finalizer 'cleaning up...'

You can check methods called by all instances of a class by the same query methods wth spy.

>> spy_of_instances(YourCoolClass).received? :your_cool_method, 'and', 'args'
=> true

>> spy_of_instances(YourCoolClass).count_received :your_lovely_method
=> 2

>> spy_of_instances(YourCoolClass).received_messages.last.method_name == :your_finalizer
=> true

In addition, you can check which instance calles a method as well as its arguments.

>> spy_of_instances(YourCoolClass).received_with_receiver? instance1, :your_cool_method
=> true
>> spy_of_instances(YourCoolClass).received_with_receiver? instance2, :your_cool_method
=> false

>> spy_of_instances(YourCoolClass).count_received_with_receiver instance1, :your_lovely_method
=> 0
>> spy_of_instances(YourCoolClass).count_received_with_receiver instance2, :your_lovely_method
=> 2

>> spy_of_instances(YourCoolClass).received_messages_with_receiver.last.receiver == instance1
=> true

Note that spy_of_instances stops spying after called methods with with_receiver (or with_receiver?) prefix. This is to prevent the spy from unexpectedly logging methods used to compare its receiver (such as ==).

>> spy_into_instances(YourCoolClass::Again)
>> instance = YourCoolClass::Again.new

>> instance.your_another_method
>> # Stops spying here.
>> spy_of_instances(YourCoolClass::Again).received_with_receiver? instance, :your_another_method

>> # Perhaps you don't want to log methods in test code.
>> instance.some_method_for_testing
>> spy_of_instances(YourCoolClass::Again).received? :some_method_for_testing
=> false

If you want to restart spying, use restart method literally.

>> spy_of_instances(YourCoolClass::Again).restart

>> instance.some_method_for_testing
>> spy_of_instances(YourCoolClass::Again).received? :some_method_for_testing
=> true

Stub Methods of Instances of a Class

>> spy_of_instances(YourCoolClass).stub(your_lovely_method: 'Even more lovely!', your_cool_method: 'much cooler!')

>> instance1.your_lovely_method
=> "Even more lovely!"
>> instance2.your_cool_method
=> "much cooler!"

Stub Methods of a Double

Double can call Spy's method directly. You do NOT need to write code such as spy(your_double).stub(...).
Just your_double.stub(...).

>> your_awesome_double = double('your awesome double', nice!: '+1!', sexy?: true)
>> your_awesome_double.nice!
=> "+1!"
>> your_awesome_double.sexy?
=> true

>> your_awesome_double.stub(:another_method, 'can be stubbed.')
>> your_awesome_double.another_method
=> "can be stubbed."

Spy on a Double

A double is spied without spy_into-ing.
And as double.stub(...), Double can also call Spy's method such as received?

>> your_awesome_double.received? :nice!
=> true
>> your_awesome_double.count_received :another_method
=> 1

Stub Constants

Specify the fully qualified name of the constant instead of the constant itself.

>> YourCoolClass::YOUR_COOL_CONST
=> "value before stubbed"

>> stub_const 'YourCoolClass::YOUR_COOL_CONST', 'more cool value!'
>> YourCoolClass::YOUR_COOL_CONST
=> "more cool value!"

Configure Methods which Spy Should NOT Log

Sometimes, you may want to make a spy ignore some methods.

>> x = YourCoolClass.new
>> spy_into x, except: [:method_to_ignore1, :method_to_ignore2]
>> x.method_to_ignore1
>> x.method_to_ignore2
>> x.your_cool_method

>> spy(x).received? :method_to_ignore1
=> false
>> spy(x).received? :method_to_ignore2
=> false
>> spy(x).received? :your_cool_method
=> true

Embedding Crispy into your Testing Framework

Remember to reset all the changes made by Crispy, call CrispyWorld.reset.

>> CrispyWorld.reset

>> spy(object).count_received :your_cool_method
=> 0
>> spy(object).count_received :your_lovely_method
=> 0
>> spy(object).received? :your_finalizer
=> false

>> object.your_cool_method
=> "cool!"
>> object.your_lovely_method
=> "lovely!"
>> YourCoolClass::YOUR_COOL_CONST
=> "value before stubbed"

Contributing

  1. Fork it ( https://github.com/igrep/crispy/fork )
  2. Create your feature branch (git checkout -b your-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin your-new-feature)
  5. Create a new Pull Request

FAQs

Package last updated on 29 Apr 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc