rails testでエラー「syntax error, unexpected end-of-input, expecting end (SyntaxError)」が発生する原因とその解消法

[Railsチュートリアル](https://railstutorial.jp/)の第6章にて、rails testでエラーが発生して行き詰まりました。
何とか解消できたのでメモ。

具体的には、[6.2.4 フォーマットを検証する](https://railstutorial.jp/chapters/modeling_users?version=5.1#sec-format_validation)でメールフォーマットの検証に関するテストを作成し、rails testを行ったところで下記のエラーが発生しました。
<br>

```ruby
$ ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 4127
Traceback (most recent call last):
        26: from -e:1:in `<main>'
        25: from /home/ec2-user/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require’
        24: from /home/ec2-user/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require’
        23: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:286:in `load’
        22: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:258:in `load_dependency’
        21: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:286:in `block in load’
        20: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:286:in `load’
        19: from /home/ec2-user/environment/sample_app/bin/rails:9:in `<top (required)>'
        18: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require’
        17: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:258:in `load_dependency’
        16: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `block in require’
        15: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require’
        14: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/commands.rb:16:in `<top (required)>'
        13: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/command.rb:44:in `invoke’
        12: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/command/base.rb:63:in `perform’
        11: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch’
        10: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command’
         9: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-0.20.3/lib/thor/command.rb:27:in `run’
         8: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/commands/test/test_command.rb:38:in `perform’
         7: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/test_unit/runner.rb:39:in `run’
         6: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/test_unit/runner.rb:50:in `load_tests’
         5: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/test_unit/runner.rb:50:in `each’
         4: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/railties-5.1.6/lib/rails/test_unit/runner.rb:50:in `block in load_tests’
         3: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require’
         2: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:258:in `load_dependency’
         1: from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `block in require’
/home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require’: /home/ec2-user/environment/sample_app/test/models/user_test.rb:56: syntax error, unexpected end-of-input, expecting end (SyntaxError)
```

<br>
ずらっとエラーが並んでいますが、怪しそうなのは一番最後のここ。

```
 syntax error, unexpected end-of-input, expecting end (SyntaxError)
```

SyntaxErrorとは構文エラーのことで、ググると【endが多いか足りない場合に発生するエラー】だと分かりました。


<br>
そこで、直前にテストを追記した user_test.rb ファイルを見てみると、、、、

```ruby:sample_app/test/models/user_test.rb
require ‘test_helper’class UserTest < ActiveSupport::TestCase
 def setup
   @user = User.new(name: “Example User”, email: “user@example.com”)
 end

 test “should be valid” do
   assert @user.valid?
 end

 test “name should be present” do
   @user.name = ”     ”
   assert_not @user.valid?
 end

 test “email should be present” do
   @user.email = ”     ”
   assert_not @user.valid?
 end

 test “name should not be too long” do
   @user.name = “a” * 51
   assert_not @user.valid?
 end

 test “email should not be too long” do
   @user.email = “a” * 244 + “@example.com”
   assert_not @user.valid?
 end

 test “email validation should accept valid addresses” do
   valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                        first.last@foo.jp alice+bob@baz.cn]
   valid_addresses.each do |valid_address|
     @user.email = valid_address
     assert @user.valid?, “#{valid_address.inspect} should be valid”
 end

 test “email validation should reject invalid addresses” do
   invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                          foo@bar_baz.com foo@bar+baz.com]
   invalid_addresses.each do |invalid_address|
     @user.email = invalid_address
     assert_not @user.valid?, “#{invalid_address.inspect} should be invalid”
 end

 test “email addresses should be unique” do
   duplicate_user = @user.dup
   @user.save
   assert_not duplicate_user.valid?
 end

end
```

なんと、each do ~ に対応する end が抜けていました。。。

下記のように end を付け足して、無事エラー解消。

<br>
＜改善後のコード＞

```ruby:sample_app/test/models/user_test.rb
.
.
 test “email validation should accept valid addresses” do
   valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                        first.last@foo.jp alice+bob@baz.cn]
   valid_addresses.each do |valid_address|
     @user.email = valid_address
     assert @user.valid?, “#{valid_address.inspect} should be valid”
   end
 end 

 test “email validation should reject invalid addresses” do
   invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                          foo@bar_baz.com foo@bar+baz.com]
   invalid_addresses.each do |invalid_address|
     @user.email = invalid_address
     assert_not @user.valid?, “#{invalid_address.inspect} should be invalid”
   end
 end 
.
.
```

<br>
rails test が通るようになりました！

```ruby
$ ec2-user:~/environment/sample_app (modeling-users) $ rails t
Running via Spring preloader in process 4360
Run options: --seed 63342# Running:..............Finished in 4.037032s, 3.4679 runs/s, 7.4312 assertions/s.14 runs, 30 assertions, 0 failures, 0 errors, 0 skips
```



# まとめ
rails test で SyntaxError エラーが発生
→ テストコードに end が足りていないのが原因でした。

SyntaxError が発生した場合、どのような構文でエラーになっているのか(今回ならunexpected end-of-input, expecting endの部分)をきちんと確かめて、コードを見直しましょう。

初歩的なミスでしたが、エラーがずらっと並んだのでどこでググっていいのか分からなかった。。。
日々勉強して、脱・初心者！