Ruby:正在解析 csv 文件并需要一些文本

Ruby: parsing over a csv file and expecting some text

我有一些日志需要分析以检查日志是否没有异常并且可以说是不正确的形式。

我已经为它生成了一个 CSV 文件:

"timestamp","source","message
"2021-10-18T09:12:29.000Z","Storage","Storage apache: [18/Oct/2021:09:12:29 +0800] 10.102.141.82 - GET /deviceManager/rest/
"2021-10-18T09:12:29.000Z","Storage","Storage apache: [18/Oct/2021:09:12:29 +0800] 10.102.141.82 - GET /deviceManager/rest/
"2021-10-18T09:12:29.000Z","Storage","Storage apache: [18/Oct/2021:09:12:29 +0800] 10.102.141.82 - GET /deviceManager/rest/
"2021-10-18T09:12:29.000Z","Storage","Storage apache: [18/Oct/2021:09:12:29 +0800] 10.102.141.82 - GET /deviceManager/rest/

我使用 CSV gem 到 parse/read 这个文件,并使用 RSpec 测试来期望一些 value/text/time 格式等。我在下面编写了代码。例如,它采用从 8 到 12 的行,我希望这些行中有一个名为“Huawei”f.e 的文本。

    RSpec.describe "Log parsing" do
    it 'returns the source' do
      table = CSV.read("Messages_result.csv")
      puts arr = table.values_at(8..12)
      arr.each do |rows|
         expect(rows).to include('Huawei')
      end
    end
end

我遇到的问题是它总是对第一行执行期望,但我想 parse/iterate 遍历整个 CSV 文件,并且还应该向我显示每一行的结果。我期望的消息当然会改变,但我只想先检查一下像华为这样的基本文本。有人可以告诉我做错了什么吗,因为理论上每个做的事情都应该遍历完整的行并对每个行提出期望?

i want to parse/iterate through the whole csv file and should as well show me for each line a result.

这不可能,请参阅 Add a configuration option to continue on failure

就是说,通过稍微修改代码,您可以 Rspec 检查整个文件并 显示 所有未通过 expect 的行:

RSpec.describe "Log parsing" do
  CSV.foreach("Messages_result.csv", :headers => true) do |row|
    it 'returns the source' do
      expect(row.to_h.values).to include("Huawei")
    end
  end
end

输出:

FF

Failures:

  1) Log parsing returns the source
     Failure/Error: expect(row.to_h.values).to include("Huawei")
       expected ["2021-10-18T09:10:29.000Z", "Storage", "Storage apache: [18/Oct/2021:09:10:29 +0800] 10.102.141.82 - GET /deviceManager/rest/"] to include "Huawei"
     # ./Messages_result.rb:10:in `block (3 levels) in <main>'

  2) Log parsing returns the source
     Failure/Error: expect(row.to_h.values).to include("Huawei")
       expected ["2021-10-18T09:11:24.000Z", "Storage", "Storage apache: [18/Oct/2021:09:11:24 +0800] 10.102.141.82 -...../license/feature HTTP/1.1 python-requests/2.21.0 - - application/json - / gzip, deflate 200 49 0"] to include "Huawei"
     # ./Messages_result.rb:10:in `block (3 levels) in <main>'

  3) ...

如果您真的想为 CSV 的每一行显示一条消息,那么您别无选择,只能自己打印。例如:

# get the output stream that Rspec is currently using
ostream = RSpec.configure { |c| c.output_stream }

# define a few colorization helpers
if ostream.tty?
  def red str; "\e[31m#{str}\e[0m"; end
  def green str; "\e[32m#{str}\e[0m"; end
else
  def red str; str; end
  def green str; str; end
end

RSpec.describe "Log parsing" do
  it 'returns the source' do
    ostream.puts
    ostream.puts "  -) Log parsing returns the source - details"
    expected = "Huawei"
    success = true
    CSV.foreach("Messages_result.csv", :headers => true) do |row|
      values = row.to_h.values
      detail = "expected #{values} to include #{expected.inspect}"
      ostream.print ' ' * 5
      if values.include?(expected)
        ostream.puts green("PASSED: #{detail}")
      else
        ostream.puts red("FAILED: #{detail}")
        success = false
      end
    end
    ostream.puts
    ostream.flush
    expect(success).to be(true)
  end
end