Bagaimana saya bisa mengabaikan warna baris perintah untuk perintah yang dijalankan dalam rspec

Saya sedang menulis permata rubi menggunakan Commander yang menggunakan templat erb dan $terminal.color untuk beberapa keluaran. Saat menulis pengujian di RSpec (menggunakan Tes CLI) saya ingin dapat memberikan opsi ke perintah saya untuk mencegah pewarnaan sehingga pengujian saya dapat mencocokkan string sederhana daripada harus menyertakan pemformatan dalam perbandingan string saya.

Saat ini saya menggunakan:

execute_script('mycommand arg1')
expect(last_execution.stdout).to include("Expected Colorized Output")

Tapi misalkan kata "Berwarna" dicetak tebal, tes ini akan gagal karena dikelilingi oleh karakter lain jadi saya harus menulis tes saya seperti ini

execute_script('mycommand arg1')
expect(last_execution.stdout).to include("Expected")
expect(last_execution.stdout).to include("Colorized")
expect(last_execution.stdout).to include("Output")

Saya ingin menghindari penghentian pengujian dengan cara ini -- adakah cara agar saya dapat meneruskan opsi dalam panggilan execute_script dalam pengujian saya, atau mengonfigurasi RSpec untuk menghapus pemformatan pengujian?

Contoh string yang dilihat RSpec

# successfully is bolded here
Command ran \e[1m\e[32msuccessfully\e[0m

Yang mana saya ingin bisa melawannya

expect(last_execution.stdout).to include("Command ran successfully")

person Rabbott    schedule 04.08.2016    source sumber
comment
Bisakah Anda membungkus include("Expected Colorized Output") dengan pewarnaan, seperti include(bold(red("Expected Colorized Output"))) --- secara harfiah membuat sintaksis ini, tetapi sesuatu seperti itu mungkin akan berhasil?   -  person jefflunt    schedule 04.08.2016
comment
Idenya adalah template itu sendiri tidak penting, jadi jika warnanya merah, hijau, atau tebal, pengujiannya akan tetap lulus. 'Desain' template bisa berubah sedikit, tapi salinannya tidak.   -  person Rabbott    schedule 04.08.2016
comment
Hm. Bisakah Anda memasukkan keluaran mentah (yang dapat dilihat oleh rspec) dalam pertanyaan Anda? Yaitu. cetak last_execution.stdout ke konsol sehingga Anda (dan kami) dapat melihat apa yang dilihat rspec?   -  person jefflunt    schedule 04.08.2016
comment
Memperbarui pertanyaan dengan sebuah contoh   -  person Rabbott    schedule 04.08.2016
comment
Ah. Mungkin Anda cukup menguji string successfully, karena itu menunjukkan status, dan merupakan string yang tidak terputus dalam pewarnaan.   -  person jefflunt    schedule 04.08.2016
comment
Itulah yang saya lakukan, dan tentukan dalam pertanyaan bahwa saya mencoba menghindarinya.   -  person Rabbott    schedule 04.08.2016
comment
Mari kita melanjutkan diskusi ini dalam chat.   -  person jefflunt    schedule 04.08.2016


Jawaban (2)


Cobalah untuk menghapus simbol escape ANSI dari string dengan RegExp berikut: /\e\[(\d+)m/

"Command ran \e[1m\e[32msuccessfully\e[0m".gsub(/\e\[(\d+)m/, "")
 => "Command ran successfully"

RegExp diambil dari ansi gem https://github.com/rubyworks/ansi

https://github.com/rubyworks/ansi/blob/17002348d45ce9298a1a4017dc43d3cf65151bd4/lib/ansi/code.rb#L44

https://github.com/rubyworks/ansi/blob/17002348d45ce9298a1a4017dc43d3cf65151bd4/lib/ansi/code.rb#L193-L208

Saya tidak yakin apakah regexp ini yang paling tepat untuk pekerjaan ini. Saya menemukan yang lain di jawaban ini: Bagaimana cara menghapus urutan escape ANSI dari string dengan python

/(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]/

Jawaban mengacu pada standar yang sesuai jadi mungkin yang ini lebih lengkap.

person SunnyMagadan    schedule 04.08.2016
comment
Ini patut dicoba -- saya akan melihat apakah saya tidak dapat menulis pencocokan khusus untuk memotongnya dan melaporkannya kembali -- terima kasih! - person Rabbott; 04.08.2016
comment
Sayangnya Ruby (rubular) tidak menyukai regex yang Anda sarankan, tetapi melalui kombinasi klik yang berasal dari tautan Anda di atas (sangat membantu saya dengan kata-kata dalam permintaan pencarian saya) saya dapat menemukan /\e\[\d+m/ sebagai pengganti yang kuat untuk itu. Saya telah memasukkan solusi akhir saya dalam sebuah jawaban -- terima kasih atas bantuan Anda! - person Rabbott; 05.08.2016
comment
Maaf, saya melewatkan regex di awal jawaban Anda, hanya melihat yang di bawah -- solusi Anda adalah regex yang saya cari, saya telah menyertakan jawaban di bawah ini yang menunjukkan implementasi regex saya yang sebenarnya. - person Rabbott; 05.08.2016

Menggunakan regex @SunnyMagadan /\e\[\d+m/ yang berhasil menemukan lokasi pewarnaan. Daripada harus memasukkan ini ke dalam semua pengujian saya, saya memperluas kelas Eksekusi CliTest dan menambahkan metode stripped_stdout yang hanya menggunakan regex untuk menghapus stdout yang sudah ditentukan oleh kelas tersebut.

Saya menambahkan kode ini ke file di /spec/support dan mengimpornya ke spec_helper.rb saya

module CliTest
  class Execution
    # Strips out ansi colorization leaving unformatted text
    def stripped_stdout
      @stdout.gsub(/\e\[\d+m/, '')
    end
  end
end

Ini memungkinkan saya untuk menggunakan yang berikut ini dalam pengujian saya

expect(last_execution.stripped_stdout).to include("Expected Colorized Output")

Itu adalah solusi yang saya senangi. Ini tidak mengganggu fungsi lainnya dan memungkinkan saya untuk tetap menggunakan last_execution.stdout jika/kapan saya mau.

person Rabbott    schedule 05.08.2016