Rspec:为自定义类测试循环数组,input = [],output = [].红宝石

use*_*371 2 ruby arrays loops rspec ruby-on-rails

我正在尝试使用我用于在输出中开发函数的示例来加速我的测试开发.

我有两个数组:输入和输出.

function(input[0]) == output[0].

循环正在运行,但它会卡在最后一个索引中.例如:如果input.length = 10,它总是执行功能(输入[10])==输出[10].

describe "multiple_chords" do
  input = ["A7 DMaj79", "E-7 A7", "D-7 G7", "Bb-7b5 Eb7b9" , "Bb-7b5 Eb7", "G7 A7", "D-7b5 G7b9", "D-79 G#7913"]
  output = [[{"root"=>"A", "def"=>"7"}, {"root"=>"D", "def"=>"Maj7"}], [{"root"=>"E", "def"=>"-7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7"}, {"root"=>"G", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "def"=>"7"}], [{"root"=>"G", "def"=>"7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7b5"}, {"root"=>"G", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]]

  for i in 0..input.length-1
    it "analyzes correctly #{input[i]}" do
      expect(IpmChords::multiple_chords(input[i])).to eq(output[i])
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

控制台中的输出是:

 6) IpmChords multiple_chords analyzes correctly Bb-7b5 Eb7
 Failure/Error: expect(IpmChords::multiple_chords(input[i])).to eq(output[i])

   expected: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
        got: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>"13", "def"=>""}]

   (compared using ==)

   Diff:
   @@ -1,3 +1,3 @@
    [{"root"=>"D", "tensions"=>"9", "def"=>"-7"},
   - {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
   + {"root"=>"G#", "tensions"=>"13", "def"=>""}]

 # ./spec/ipm_classes/ipm_chords_ipm_class_spec.rb:28:in `block (4 levels) in <top (required)>'

7) IpmChords multiple_chords analyzes correctly E-7 A7
 Failure/Error: expect(IpmChords::multiple_chords(input[i])).to eq(output[i])

   expected: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
        got: [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>"13", "def"=>""}]

   (compared using ==)

   Diff:
   @@ -1,3 +1,3 @@
    [{"root"=>"D", "tensions"=>"9", "def"=>"-7"},
   - {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]
   + {"root"=>"G#", "tensions"=>"13", "def"=>""}]
Run Code Online (Sandbox Code Playgroud)

您可以看到它总是在评估相同的数组索引,但每个循环迭代的测试名称都在变化:

6) IpmChords multiple_chords analyzes correctly Bb-7b5 Eb7
7) IpmChords multiple_chords analyzes correctly E-7 A7
Run Code Online (Sandbox Code Playgroud)

我认为这将是一个很好的节省时间,它应该工作,不?希望您能够帮助我.谢谢

Chr*_*ald 6

你在这里遇到Ruby的块绑定遇到了一些问题.发生的事情是每个块都要绑定到i,它仍然在范围内,这意味着它们被调用,它们都将使用i最终的结果(这将是最后一个数组索引).

如果您改为使用Ruby的块迭代器,它将起作用:

describe "multiple_chords" do
  input = ["A7 DMaj79", "E-7 A7", "D-7 G7", "Bb-7b5 Eb7b9" , "Bb-7b5 Eb7", "G7 A7", "D-7b5 G7b9", "D-79 G#7913"]
  output = [[{"root"=>"A", "def"=>"7"}, {"root"=>"D", "def"=>"Maj7"}], [{"root"=>"E", "def"=>"-7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7"}, {"root"=>"G", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"Bb", "def"=>"-7b5"}, {"root"=>"Eb", "def"=>"7"}], [{"root"=>"G", "def"=>"7"}, {"root"=>"A", "def"=>"7"}], [{"root"=>"D", "def"=>"-7b5"}, {"root"=>"G", "tensions"=>"b9", "def"=>"7"}], [{"root"=>"D", "tensions"=>"9", "def"=>"-7"}, {"root"=>"G#", "tensions"=>["9", "13"], "def"=>"7"}]]

  input.each_with_index do |chord, index|
    it "analyzes correctly #{chord}" do
      expect(IpmChords::multiple_chords(chord)).to eq(output[index])
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

这样做的原因是你最终不会在每个块之外创建一个保留在作用域内的变量,因此每个块最终都会被调用正确的值.每个循环产生的值都是该循环的局部值,因此您不会"流失".

另外,惯用的Ruby通常期望使用枚举器而不是循环.

关于风格的说明; 你可以通过定义然后迭代预期输入和输出的散列来清理这一点:

describe "multiple_chords" do
  CHORD_MAP = {
    "A7 DMaj79" => [{"root"=>"A", "def"=>"7"}, {"root"=>"D", "def"=>"Maj7"}],
    "E-7 A7"    => [{"root"=>"E", "def"=>"-7"}, {"root"=>"A", "def"=>"7"}],
    # ...
  }

  CHORD_MAP.each do |chord, result|
    it "analyzes correctly #{chord}" do
      expect(IpmChords::multiple_chords(chord)).to eq(result)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)