W4D3 Flashcards
Raise
Generic way to end runtime. Hardcodes an error given a condition.
raise “Something Went wrong” if some condition
Begin/Rescue>Retry Block
Protects against errors resulting from User input.
Wrap a function call in a Begin/Rescue block. Include Retry to loop back to Begin
class CustomError < StandardError
raise CustomError.new(“Something went wrong”)
Custom error class ‘CustomError’ is created and inherits from StandardError
creates a new instance to include with a Rescue block.
Ensure
Ensure block only runs after a Begin/Rescue block completes. It will ALWAYS run regardless
Begin > Rescue > Retry
Interrupting the Retry Loop
Raise a conditional error before the Rescue.
example:
if raise “too many tried” if password_attempts > 2
Require bank
require multiple files in a separate file and keep your main class clean
Singleton Module
@sentinel = Singleton.instance
can be used to reference a single instance value for any filler spaces
loop do
break unless
loop continually and check for break conditions
rspec files
require ‘rspec’
require ‘file’
project lib/ file.rb spec/ file_spec.rb
rspec test
describe block
it block
Organizes your test and gives them lables
describe “#method_name” do
it “returns ‘Something!” do
expect(method_name).to eq(“Something!”
describe
DESCRIBE the “Subject” > do
IT “tests the case” do
EXPECT( {CODE} ).TO
Class do
“::class_method” “#instance_method” do
Nesting describe
Nest ‘describe’ or its alias ‘context’
expect
does the work of testing your code
Match between a value generated and an expected value
expect values
expect(test_value).to
expect(test_value).to_not
expect() AND expect{ }
expecting operations vs expecting errors
RSPEC matchers
.to eq(expected_val) and .to be(expected_val)
== or is the same object
Rspec Expectations
lets you express expected outcomes on an obect in an example
install rspec
Want to run against the main branch? You’ll need to include the dependent RSpec repos as well. Add the following to your Gemfile:
%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
gem lib, :git => “https://github.com/rspec/#{lib}.git”, :branch => ‘main’
end
Built-in Matchers -Equivalence
expect(actual).to eq(expected) # passes if actual == expected
expect(actual).to eql(expected) # passes if actual.eql?(expected)
expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected))
Built-in Matchers -
Identity
expect(actual).to be(expected) # passes if actual.equal?(expected)
expect(actual).to equal(expected) # passes if actual.equal?(expected)
Built-in Matchers - Comparisons
expect(actual).to be > expected expect(actual).to be >= expected expect(actual).to be <= expected expect(actual).to be < expected expect(actual).to be_within(delta).of(expected)
Built-in Matchers - Types/classes
expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected
expect(actual).to be_a(expected) # passes if actual.kind_of?(expected)
expect(actual).to be_an(expected) # an alias for be_a
expect(actual).to be_a_kind_of(expected) # another alias
Built-in Matchers - Truthiness
expect(actual).to be_truthy # passes if actual is truthy (not nil or false)
expect(actual).to be true # passes if actual == true
expect(actual).to be_falsy # passes if actual is falsy (nil or false)
expect(actual).to be false # passes if actual == false
expect(actual).to be_nil # passes if actual is nil
expect(actual).to_not be_nil # passes if actual is not nil
Built-in Matchers - Expecting errors
expect { … }.to raise_error
expect { … }.to raise_error(ErrorClass)
expect { … }.to raise_error(“message”)
expect { … }.to raise_error(ErrorClass, “message”)
Built-in Matchers - Expecting throws
expect { … }.to throw_symbol
expect { … }.to throw_symbol(:symbol)
expect { … }.to throw_symbol(:symbol, ‘value’)
Built-in Matchers others
Yielding, Predicate matchers, Ranges (Ruby >= 1.9 only),
Built-in Matchers - Collection membership
# exact order, entire collection expect(actual).to eq(expected)
exact order, partial collection (based on an exact position)
expect(actual).to start_with(expected)
expect(actual).to end_with(expected)
# any order, entire collection expect(actual).to match_array(expected)
# You can also express this by passing the expected elements # as individual arguments expect(actual).to contain_exactly(expected_element1, expected_element2)
# any order, partial collection expect(actual).to include(expected)
expect([1, 2, 3]).to eq([1, 2, 3]) # Order dependent equality check
expect([1, 2, 3]).to include(1) # Exact ordering, partial collection matches
expect([1, 2, 3]).to include(2, 3) #
expect([1, 2, 3]).to start_with(1) # As above, but from the start of the collection
expect([1, 2, 3]).to start_with(1, 2) #
expect([1, 2, 3]).to end_with(3) # As above but from the end of the collection
expect([1, 2, 3]).to end_with(2, 3) #
expect({:a => ‘b’}).to include(:a => ‘b’) # Matching within hashes
expect(“this string”).to include(“is str”) # Matching within strings
expect(“this string”).to start_with(“this”) #
expect(“this string”).to end_with(“ring”) #
expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches
expect([1, 2, 3]).to match_array([3, 2, 1]) #
Order dependent compound matchers
expect(
[{:a => ‘hash’},{:a => ‘another’}]
).to match([a_hash_including(:a => ‘hash’), a_hash_including(:a => ‘another’)])
Built-in Matchers - Compound Matcher Expressions
expect(alphabet).to start_with(“a”).and end_with(“z”)
expect(stoplight.color).to eq(“red”).or eq(“green”).or eq(“yellow”)
RSPEC - Before block
describe Chess do
let(:board) { Board.new }
describe '#checkmate?' do context 'when in checkmate' do before(:each) do board.make_move([3, 4], [2, 3]) board.make_move([1, 2], [4, 5]) board.make_move([5, 3], [5, 1]) board.make_move([6, 3], [2, 4]) end
before(:each) do
execute the block of code before each spec in that describe block
describe ‘#valid_move?’ do
it ‘should return false for wrong colored pieces’
it ‘should return false for moves that are off the board’
it ‘should return false for moves that put you in check’
end
Leave off the do…end from the it. for pending specs
RSPEC, instantiate an instance of an Object
Subject and It
describe Robot do
subject(:robot) { Robot.new }
it “position should start at [0, 0]” do
expect(robot.position).to eq([0, 0])
end
describe "move methods" do it "moves left" do robot.move_left expect(robot.position).to eq([-1, 0]) end end end
Subject block
defines the subject of the test
subject also accepts a block that constructs the subject. You can do any necessary setup inside the block.
there can only be one unnamed subject
Let block
defines the helper objects that interact with the subject
there can be multiple helper objects
let does not persist state
You might read that let memoizes its return value. Memoization means that the first time the method is invoked, the return value is cached and that same value is returned every subsequent time the method is invoked within the same scope. Since every it is a different scope, let does not persist state between those specs.