subject

#### `subject`はトップレベルグループスコープで定義され、使われることができる
>### A subject can be defined and used in the top level group scope

```rb
RSpec.describe Array, "with some elements" do
  subject { [1, 2, 3] }

  it "has the prescribed elements" do
    expect(subject).to eq([1, 2, 3])
  end
end
```
```
Run options: include {:full_description=>/Array\ with\ some\ elements/}
1 example, 0 failures, 1 passed
```
#### 外部グループで定義された`subject`は内部グループが使用可能である
>### The subject defined in an outer group is available to inner groups

```rb
RSpec.describe Array do
  subject { [1, 2, 3] }

  describe "has some elements" do
    it "which are the prescribed elements" do
      expect(subject).to eq([1, 2, 3])
    end
  end
end
```
```
Run options: include {:full_description=>/Array/}
1 example, 0 failures, 1 passed
```
#### `subject`はexample内でメモされるしかしexample間はできない
>### The subject is memoized within an example but not across examples

このシナリオは`subject`定義ブロックで実行される突然変異を示す。この振る舞いは、仕様理解をより難しくとして振る舞いとして一般的に推奨されていないさせる。これはどれくらいメモライゼーションを起こさせるかを説明するためのツールとして簡単に使える技術です。
>Note: This scenario shows mutation being performed in a subject definition block. This behavior is generally discouraged as it makes it more difficult to understand the specs. This is technique is used simply as a tool to demonstrate how the memoization occurs.

```rb
RSpec.describe Array do
  # This uses a context local variable. As you can see from the
  # specs, it can mutate across examples. Use with caution.
  element_list = [1, 2, 3]

  subject { element_list.pop }

  it "is memoized across calls (i.e. the block is invoked once)" do
    expect {
      3.times { subject }
    }.to change{ element_list }.from([1, 2, 3]).to([1, 2])
    expect(subject).to eq(3)
  end

  it "is not memoized across examples" do
    expect{ subject }.to change{ element_list }.from([1, 2]).to([1])
    expect(subject).to eq(2)
  end
end
```
```
Run options: include {:full_description=>/Array/}
2 examples, 0 failures, 2 passed
```
changeマッチャーによって確認されているらしい

#### `subject`は`before`フックの前に利用可能である
>### The subject is available in before hooks

```rb
RSpec.describe Array, "with some elements" do
  subject { [] }

  before { subject.push(1, 2, 3) }

  it "has the prescribed elements" do
    expect(subject).to eq([1, 2, 3])
  end
end
```
#### ヘルパーメソッドは`subject`定義ブロックから呼び出ことができる
>### Helper methods can be invoked from a subject definition block

```rb
RSpec.describe Array, "with some elements" do
  def prepared_array
    [1, 2, 3]
  end

  subject { prepared_array }  

  it "has the prescribed elements" do
    expect(subject).to eq([1, 2, 3])
  end
end
```
```
Run options: include {:full_description=>/Array\ with\ some\ elements/}
1 example, 0 failures, 1 passed
```
`We recommend using the named helper method over subject in examples.`なのでヘルパーメソッドを使う方がいい

#### `subject!`破壊メソッドを使ってexampleの前に定義ブロックを呼び出す
>### Use the subject! bang method to call the definition block before the example

```rb
RSpec.describe "eager loading with subject!" do
  subject! { element_list.push(99) } # 破壊的メソッドを使うことで定義ブロックを呼び出してる

  let(:element_list) { [1, 2, 3] }

  it "calls the definition block before the example" do
    element_list.push(5)
    expect(element_list).to eq([1, 2, 3, 99, 5])
  end
end
```
```
Run options: include {:full_description=>/eager\ loading\ with\ subject!/}
1 example, 0 failures, 1 passed
```
* 破壊的メソッドを使うことで定義ブロックより上でも呼び出せる

#### グループ全体でテストしないと変数が初期化される
#### `subject(:name)`を使って、ヘルパーメソッドを定義する　
>### Use subject(:name) to define a memoized helper method

グローバル変数はexample下で使われる間、この振る舞いは、強硬に現在の仕様で推奨されていない。ここでは単に複数回の呼び出しにわたるキャッシュされる値を表示するしかしexampleをまたいだキャッシュされない。
>Note: While a global variable is used in the examples below, this behavior is strongly discouraged in actual specs. It is used here simply to demonstrate the value will be cached across multiple calls in the same example but not across examples.

Given a file named “namedsubjectspec.rb” with:
```rb
$count = 0

RSpec.describe "named subject" do
  subject(:global_count) { $count += 1 }

  it "is memoized across calls (i.e. the block is invoked once)" do
    expect {
      2.times { global_count }
    }.not_to change{ global_count }.from(1) # １から変わっているか？
  end

  it "is not cached across examples" do
    expect(global_count).to eq(2)
  end

  it "is still available using the subject method" do
    expect(subject).to eq(3)
  end

  it "works with the one-liner syntax" do
    is_expected.to eq(4)
  end

  it "the subject and named helpers return the same object" do
    expect(global_count).to be(subject)
  end

  it "is set to the block return value (i.e. the global $count)" do
    expect(global_count).to be($count)
  end
end
```
```
Run options: include {:full_description=>/named\ subject/}
6 examples, 0 failures, 6 passed
```
### is_expected
https://qiita.com/masatom86650860/items/3ff0810a9880008a22c9

#### subject!(:name)を使ってexampleの前に呼ばれるヘルパーメソッドを定義する
>### Use subject!(:name) to define a helper method called before the example

```rb
RSpec.describe "eager loading using a named subject!" do
  subject!(:updated_list) { element_list.push(99) }

  let(:element_list) { [1, 2, 3] }

  it "calls the definition block before the example" do
    element_list.push(5)
    expect(element_list).to eq([1, 2, 3, 99, 5])
    expect(updated_list).to be(element_list)
  end
end
```
```
Run options: include {:full_description=>/eager\ loading\ using\ a\ named\ subject!/}
1 example, 0 failures, 1 passed
```

https://rspec.info/features/3-13/rspec-core/subject/explicit-subject/

#### be
https://qiita.com/masatom86650860/items/fbe86bb46fbf88f88546

#### equalとの違いはあるのか？
```rb
RSpec.describe "eager loading using a named subject!" do
  subject!(:updated_list) { element_list.push(99) }

  let(:element_list) { [1, 2, 3] }

  it "calls the definition block before the example" do
    element_list.push(5)
    expect(element_list).to eq([1, 2, 3, 99, 5])
    expect(updated_list).to be([1, 2, 3, 99, 5])
  end
end
```
### 同一のインスタンスでないと失敗する
https://qiita.com/masatom86650860/items/fbe86bb46fbf88f88546#:~:text=%E5%90%8C%E3%81%98%E5%80%A4%E3%81%A7%E3%82%82%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%8C%E7%95%B0%E3%81%AA%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AF%E3%83%86%E3%82%B9%E3%83%88%E3%81%AF%E5%A4%B1%E6%95%97%E3%81%97%E3%81%BE%E3%81%99%E3%80%82