rubocop rspec ruby2.4-strict rule MultilineBlockLayout and NamedSubject conflict

Viewed 500

I have following rspec ruby code. I am testing some puppet modules. It throws a linting error.

Block body expression is on the same line as the block start. (convention:Layout/MultilineBlockLayout)

describe "on #{os}" do
  let(:facts) { facts }      

  it { is_expected.to contain_class('windows_some_thing::some_suite') }
  context 'with some_suite_enabled' do
    let(:params) { { cipher_suite: %w[ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ] } }

    it { is_expected.to contain_registry_value('HKLM\SOFTWARE\Policies\Microsoft\something\something\something\000000\Functions').with(
        ensure: 'present',
        type: 'string',
        data: 'ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521,ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ',
      )
    }
  end

I can use rubocop -a to fix it. However this corrects the code as per below. And then get a different linting error

Name your test subject if you need to reference it explicitly. (convention:RSpec/NamedSubject)

    it {
      expect(subject).to contain_registry_value('HKLM\SOFTWARE\Policies\Microsoft\something\something\something\000000\Functions').with(
        ensure: 'present',
        type: 'string',
        data: 'ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521,ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ',
      )
    }

How can I fix this for ruby-2.4-strict? I have more than 10000 linting errors I need to fix. spread across multiple files and modules. So I need a practical straight forward solution. I know it will be quite time consuming. But I don't want it to take rest of the year to do it.

1 Answers

A simpler and more direct correction for

Block body expression is on the same line as the block start. (convention:Layout/MultilineBlockLayout)

would involve this:

it {
  is_expected.to contain_registry_value('HKLM\SOFTWARE\Policies\Microsoft\something\something\something\000000\Functions').with(
    ensure: 'present',
    type: 'string',
    data: 'ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521,ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ',
  )
}

The rule is that the start and end delimiters of a multiline block must appear on separate lines from anything (other than whitespace) in the block body.

That, too, will still raise a flag, but one whose correction is more evident. The linter wants you to use do and end to delimit multiline blocks, so this is where you ultimately want to be:

it do
  is_expected.to contain_registry_value('HKLM\SOFTWARE\Policies\Microsoft\something\something\something\000000\Functions').with(
    ensure: 'present',
    type: 'string',
    data: 'ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521,ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ',
  )
end

Or maybe even here:

it do
  is_expected.to contain_registry_value('HKLM\SOFTWARE\Policies\Microsoft\something\something\something\000000\Functions')
    .with(
      ensure: 'present',
      type: 'string',
      data: 'ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521,ABC_ECDHE_JKL_WITH_ABC_123_RET_ABC_384_521 ',
    )
end

I find this last more readable, especially if you want to chain additional predicates.

Related