Как я могу игнорировать цвета командной строки для команд, запускаемых в rspec

Я пишу ruby ​​gem, используя Commander, который использует шаблоны erb и $terminal.color для части вывода. При написании тестов в RSpec (используя CLI Test) я хотел бы иметь возможность передать параметр к моим командам, чтобы предотвратить раскрашивание, чтобы мои тесты могли сопоставлять простые строки вместо того, чтобы включать форматирование в мои сравнения строк.

В настоящее время я использую:

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

Но предположим, что слово "Раскрашено" выделено жирным шрифтом, этот тест не пройдет, потому что он окружен другими символами, поэтому я должен написать свой тест следующим образом.

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")

Я хотел бы избежать необходимости разбивать тест таким образом - есть ли способ передать параметр в моем вызове execute_script в моих тестах или настроить RSpec для удаления форматирования для тестов?

Образец строки, которую видит RSpec

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

Что я хотел бы иметь возможность работать против

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

person Rabbott    schedule 04.08.2016    source источник
comment
Можете ли вы каким-то образом обернуть include("Expected Colorized Output") раскрашиванием, например include(bold(red("Expected Colorized Output"))) --- буквально составив этот синтаксис, но, возможно, что-то в этом роде сработает?   -  person jefflunt    schedule 04.08.2016
comment
Ну, идея в том, что сам шаблон не имеет значения, поэтому, если он красный, зеленый или полужирный, тест все равно пройдет. «Дизайн» шаблона может немного измениться, но копия не изменится.   -  person Rabbott    schedule 04.08.2016
comment
Хм. Можете ли вы включить необработанный вывод (который виден rspec) в свой вопрос? т.е. вывести last_execution.stdout в консоль, чтобы вы (и мы) могли видеть, что видит rspec?   -  person jefflunt    schedule 04.08.2016
comment
Обновил вопрос с примером   -  person Rabbott    schedule 04.08.2016
comment
Ах. Возможно, вы можете просто проверить строку successfully, так как это указывает на статус и является непрерывной строкой в ​​раскрашивании.   -  person jefflunt    schedule 04.08.2016
comment
Это то, что я делаю, и укажите в вопросе, что я пытаюсь этого избежать.   -  person Rabbott    schedule 04.08.2016
comment
Давайте продолжим обсуждение в чате.   -  person jefflunt    schedule 04.08.2016


Ответы (2)


Попробуйте удалить escape-символы ANSI из строки с помощью следующего регулярного выражения: /\e\[(\d+)m/

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

RegExp был взят из 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

Я не уверен, что это регулярное выражение является наиболее правильным для этой работы. В этом ответе я нашел еще один: Как удалить escape-последовательности ANSI из строки в Python

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

Ответ относится к соответствующим стандартам, поэтому, возможно, этот ответ является более полным.

person SunnyMagadan    schedule 04.08.2016
comment
Стоит попробовать - я посмотрю, не смогу ли я написать собственный сопоставитель, чтобы вырезать этот материал и отчитаться - спасибо! - person Rabbott; 04.08.2016
comment
Ruby (rubular), к сожалению, не любит регулярное выражение, которое вы предложили, но благодаря комбинации кликов по вашим ссылкам выше (действительно помогло мне с формулировкой моих поисковых запросов) я смог найти /\e\[\d+m/ в качестве надежной замены для него. Я включил свое окончательное решение в ответ - спасибо за вашу помощь! - person Rabbott; 05.08.2016
comment
Извините, я каким-то образом пропустил регулярное выражение в начале вашего ответа, увидел только одно внизу - ваше решение - это регулярное выражение, которое я искал, я включил ответ ниже, который показывает мою фактическую реализацию регулярное выражение. - person Rabbott; 05.08.2016

Использование регулярного выражения @SunnyMagadan /\e\[\d+m/, которое успешно находит раскрашивание. Вместо того, чтобы включать это во все мои тесты, я расширил класс CliTest Execution и добавил метод stripped_stdout, который просто использует регулярное выражение для удаления stdout, уже определенного классом.

Я добавил этот код в файл в /spec/support и импортировал его в свой spec_helper.rb.

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

Это позволяет мне использовать следующее в моих тестах

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

Это решение, которым я доволен. Это не мешает другим функциям и позволяет мне продолжать использовать last_execution.stdout, если/когда я захочу.

person Rabbott    schedule 05.08.2016