# RSpec運作模式
### gem “rspec”

### gem “rspec-rails”

## 運作模式
```ruby=
RSpec.describe "calculation" do
it "can add numbers" do
expect(1 + 1).to eq(2)
end
end
```
### describe
```ruby=
RSpec.describe "calculation" do
...
end
```
describe主要源自於example_group.rb

### it
```ruby=
it "can add numbers" do
...
end
```
it主要源自於example.rb
```ruby=
RSpec.describe "eg1" do
it "e1"
it "e2"
context "eg1_1" do
it "e3"
end
context "eg2_1" do
it "e3"
end
end
```

### hook
```ruby=
before {}
after {}
around { |ex| ex.run}
```
hooks源自於hooks.rb
```ruby=
before(:suite) / after(:suite) #只會運行一次
before(:context) / after(:context) #每個example group會運行一次
before / after /arounf #每個example都會運行一次
```
### expect & to
```ruby=
expect(1 + 1).to eq(2)
```
Expectation來自rspec-expectations


### match
```ruby=
expect(...).to match([
a_kind_of(String),
a_hash_including(a: 4)
])
```
```ruby=
[
“any string”,
{a: 4, b: 6.0},
]
```
```ruby=
class Match < BaseMatcher
def match(expected, actual)
return true if values_match?(
expected, actual)
actual.match(expected)
end
end
```
values_match?
```ruby=
def values_match?(expected, actual)
expected =
with_matchers_cloned(expected)
Support::FuzzyMatcher.values_match?(
expected, actual)
end
```
Support::FuzzyMatcher.values_match?
```ruby=
def self.values_match?(e, a)
if Hash === a
return hashes_match?(e, a) if Hash
=== e
elsif Array === e
&& Enumerable === a
&& !(Struct === a)
return arrays_match?(
e, a)
end
```
hashes_match?
```ruby=
def self.hashes_match?(
expected_hash, actual_hash)
return false if
expected_hash.size != actual_hash.size
expected_hash.all? do |e_k, e_v|
actual_value = actual_hash.fetch(e_k) {
return false }
values_match?(e_v, actual_value)
end end
```
#### Array === e
arrays_match?
```ruby=
def self.arrays_match?(
expected_list, actual_list)
return false if
expected_list.size!=actual_list.size
expected_list.zip(actual_list).all? do
|expected, actual|
values_match?(expected, actual)
end
end
```
### 值與屬性
```ruby=
def self.values_match?(expected, actual)
...
(the code we saw earlier)
return true if expected == actual
begin
expected === actual
rescue ArgumentError
# Some objects, like 0-arg lambdas on
# 1.9+, raise
# ArgumentError for `expected === actual`.
false
end
end
```
原比對內容
```ruby=
[
“any string”,
{a: 4, b: 6.0}
]
```
做了三件比對:arrays_match? / === / ===
### rspec-mocks
```ruby=
RSpec.describe "mocking" do
it “adds a foo method" do
allow(foo).to
receive(:bees)
expect(foo.bees).to eq(nil)
end
end
```


call foo.bee

## RSpec運作流程
