diff --git a/.gitignore b/.gitignore index 72ef697..61c10e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ exec-log.txt +exec.log +gen.log diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 07a4a0f..754c468 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -30,10 +30,10 @@ } }, { - "taskName": "Exec main feature", + "taskName": "Exec all features", "args": [ "${workspaceRoot}/src/bdd.os", - "${workspaceRoot}/features/core/ПрогонВсехФичПроекта.feature", + "${workspaceRoot}/features/core", "-out", "${workspaceRoot}/exec.log" ], diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..e2714c8 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,43 @@ +#!groovy +node("slave") { + def isUnix = isUnix(); + + stage "checkout" + + checkout scm + if (isUnix) {sh 'git submodule update --init'} else {bat "git submodule update --init"} + + stage "checkout oscript-library for testrunner.os" + checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'oscript-library']], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/EvilBeaver/oscript-library.git']]]) + + stage "testing with testrunner.os" + + command = """oscript ./oscript-library/tests/testrunner.os -runall ./tests xddReportPath ./tests""" + if (isUnix) {sh "${command}"} else {bat "@chcp 1251 > nul \n${command}"} + + step([$class: 'JUnitResultArchiver', testResults: '**/tests/*.xml']) + + stage "exec all features" + + command = """oscript ./src/bdd.os ./features/core -out ./bdd-exec.log""" + + def errors = [] + try{ + if (isUnix){ + sh "${command}" + } else { + bat "@chcp 1251 > nul \n${command}" + } + } catch (e) { + errors << "BDD status : ${e}" + } + + if (errors.size() > 0) { + currentBuild.result = 'UNSTABLE' + for (int i = 0; i < errors.size(); i++) { + echo errors[i] + } + } + + step([$class: 'ArtifactArchiver', artifacts: '**/bdd-exec.log', fingerprint: true]) +} \ No newline at end of file diff --git a/README.md b/README.md index 9471a50..f8a151e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # 1BDD для OneScript -1bdd - инструмент для выполнения автоматизированных требований/тестов, написанных на обычном, не программном языке. +`1bdd` - инструмент для выполнения автоматизированных требований/тестов, написанных на обычном, не программном языке. -Иными словами, это консольный фреймворк, реализующий BDD для проекта [OneScript](https://github.com/EvilBeaver/OneScript). +Иными словами, это консольный фреймворк, реализующий `BDD` для проекта [OneScript](https://github.com/EvilBeaver/OneScript). Идеи черпаются из проекта [Cucumber](https://cucumber.io). @@ -16,16 +16,12 @@ oscript bdd.os <команда> <параметры команды> [ключи] Возможные команды: [ключи] - Выполняет сценарии BDD для Gherkin-спецификаций - Параметры: - features-path - путь к файлам *.feature. - Можно указывать как каталоги, так и конкретные файлы. - + или exec [ключи] Выполняет сценарии BDD для Gherkin-спецификаций Параметры: features-path - путь к файлам *.feature. - Можно указывать как каталог, так и конкретный файл. + Можно указывать как каталоги, так и конкретные файлы. gen [ключи] Создает заготовки шагов для указанных Gherkin-спецификаций @@ -45,3 +41,62 @@ oscript bdd.os <команда> <параметры команды> [ключи] Для подсказки по конкретной команде наберите `bdd help <команда>`. + +# Формат файла шагов + +Это обычный os-скрипт, который располагает в подкаталоге `step_definitions` относительно файла фичи. + +В этом файле должна быть служебная функция `ПолучитьСписокШагов`, которая возвращает массив всех шагов, заданных в этом скрипте. + +Также внутри файла шагов могут располагаться специальные методы-обработчики (хуки) событий `ПередЗапускомСценария`/`ПослеЗапускаСценария` + +## Пример файла шагов + +``` +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯСохранилКлючИЗначениеВПрограммномКонтексте"); + ВсеШаги.Добавить("ЯПолучаюКлючИЗначениеИзПрограммногоКонтекста"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//Я сохранил ключ "Ключ1" и значение 10 в программном контексте +Процедура ЯСохранилКлючИЗначениеВПрограммномКонтексте(Знач Ключ, Знач Значение) Экспорт + БДД.СохранитьВКонтекст(Ключ, Значение); +КонецПроцедуры + +//я получаю ключ "Ключ1" и значение 10 из программного контекста +Процедура ЯПолучаюКлючИЗначениеИзПрограммногоКонтекста(Знач Ключ, Знач ОжидаемоеЗначение) Экспорт + НовоеЗначение = БДД.ПолучитьИзКонтекста(Ключ); + Ожидаем.Что(НовоеЗначение).Равно(ОжидаемоеЗначение); +КонецПроцедуры +``` + +# Программный контекст + +Для обмена информацией внутри кода реализации шагов можно использовать API контекста, предоставляемый продуктом. + +Описание: ++ `Процедура СохранитьВКонтекст(Ключ, Значение)` - сохранить значение по специальному ключу ++ `Функция ПолучитьИзКонтекста(Знач Ключ)` - возвращает значение по ключу diff --git a/features/core/Hooks.feature b/features/core/Hooks.feature new file mode 100644 index 0000000..02a191c --- /dev/null +++ b/features/core/Hooks.feature @@ -0,0 +1,47 @@ +# language: ru + +Функционал: Проверка хуков в файле шагов + Как Разработчик + Я Хочу, чтобы у меня была возможность использовать хуки ПередЗапускомСценария/ПослеЗапускаСценария в файлах шагов + +Контекст: Подготовка файла фичи "ПроверкаХуков" + Когда я подготовил тестовый каталог для фич + И установил тестовый каталог как текущий + И я создал файл фичи "ПроверкаХуков" с текстом + """ + # language: ru + Функционал: Проверка хуков + Сценарий: Запись в файл журнала + Тогда я записываю "ШагСценария" в файл журнала + """ + И я запустил генерацию шагов фичи "ПроверкаХуков" + И я получил сгенерированный os-файл "ПроверкаХуков" в ожидаемом каталоге + +Сценарий: Проверка выполнения хуков + + Тогда проверка поведения фичи "ПроверкаХуков" закончилась с кодом возврата 1 + И я подставил файл шагов фичи "ПроверкаХуков" из каталога "tests\fixtures" + И проверка поведения фичи "ПроверкаХуков" закончилась с кодом возврата 0 + И текст файла-журнала равен ";ПередЗапускомСценария-Запись в файл журнала;ШагСценария;ПослеЗапускаСценария-Запись в файл журнала" + +Контекст: Подготовка файла фичи "ПроверкаХуков" с наличием контекста + Когда я подготовил тестовый каталог для фич + И установил тестовый каталог как текущий + И я создал файл фичи "ПроверкаХуков" с текстом + """ + # language: ru + Функционал: Проверка хуков + Контекст: шаги контекста + Тогда я записываю "ШагКонтекста" в файл журнала + Сценарий: Запись в файл журнала с контекстом + Тогда я записываю "ШагСценария" в файл журнала + """ + И я запустил генерацию шагов фичи "ПроверкаХуков" + И я получил сгенерированный os-файл "ПроверкаХуков" в ожидаемом каталоге + +Сценарий: Выполнение контекста после хука ПередЗапускомСценария + + Тогда проверка поведения фичи "ПроверкаХуков" закончилась с кодом возврата 1 + И я подставил файл шагов фичи "ПроверкаХуков" из каталога "tests\fixtures" + И проверка поведения фичи "ПроверкаХуков" закончилась с кодом возврата 0 + И текст файла-журнала равен ";ПередЗапускомСценария-Запись в файл журнала с контекстом;ШагКонтекста;ШагСценария;ПослеЗапускаСценария-Запись в файл журнала с контекстом" diff --git a/features/core/step_definitions/Hooks.os b/features/core/step_definitions/Hooks.os new file mode 100644 index 0000000..a2bdd74 --- /dev/null +++ b/features/core/step_definitions/Hooks.os @@ -0,0 +1,63 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +#Использовать asserts + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯПодставилФайлШаговФичиИзКаталога"); + ВсеШаги.Добавить("ТекстФайла_ЖурналаРавен"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +//я подставил файл шагов фичи "ПроверкаХуков" из каталога "tests\fixtures" +Процедура ЯПодставилФайлШаговФичиИзКаталога(Знач ИмяФичи, Знач КаталогФичи) Экспорт + ИмяИсполнителяШагов = ИмяФичи + ".os"; + ИсходныйФайлИсполнителяШагов = Новый Файл(ОбъединитьПути(КаталогПроекта(), КаталогФичи, "step_definitions", ИмяИсполнителяШагов )); + ФайлИсполнителяШагов = Новый Файл(ОбъединитьПути("step_definitions", ИмяИсполнителяШагов )); + + Если ФайлИсполнителяШагов.Существует() Тогда + УдалитьФайлы(ФайлИсполнителяШагов.ПолноеИмя); + КонецЕсли; + КопироватьФайл(ИсходныйФайлИсполнителяШагов.ПолноеИмя, ФайлИсполнителяШагов.ПолноеИмя); +КонецПроцедуры + +//текст файла-журнала равен "ПередЗапускомСценария;ШагСценария" +Процедура ТекстФайла_ЖурналаРавен(Знач ТекстЖурнала) Экспорт + СтрокаИзЖурнала = ПрочитатьЖурнал(); + Ожидаем.Что(СтрокаИзЖурнала).Равно(ТекстЖурнала); +КонецПроцедуры + +//TODO дубль с ПроверкаХуков.os +Функция ПрочитатьЖурнал() + ФайлЖурнала = Новый Файл(ПутьФайлаЖурнала()); + Если ФайлЖурнала.Существует() Тогда + + ЧтениеТекста = Новый ЧтениеТекста; + ЧтениеТекста.Открыть(ПутьФайлаЖурнала(),"UTF-8"); + + СтрокаИзЖурнала = ЧтениеТекста.ПрочитатьСтроку(); + ЧтениеТекста.Закрыть(); + Иначе + СтрокаИзЖурнала = ""; + КонецЕсли; + Возврат СтрокаИзЖурнала; +КонецФункции + +//TODO дубль с ПроверкаХуков.os +Функция ПутьФайлаЖурнала() + Возврат "ФайлЖурнала.log"; +КонецФункции // ПутьФайлаЖурнала() + +Функция КаталогПроекта() Экспорт + КаталогПроекта = ОбъединитьПути(ТекущийСценарий().Каталог, "..", "..", ".."); + Возврат КаталогПроекта; +КонецФункции // ПолучитьКаталогИсходников() diff --git "a/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" "b/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" new file mode 100644 index 0000000..62d3358 --- /dev/null +++ "b/features/core/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.os" @@ -0,0 +1,95 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("УстановилКаталогПроектаКакТекущий"); + ВсеШаги.Добавить("ВЛог_ФайлеЗапускаПродуктаЕстьСтрока"); + ВсеШаги.Добавить("ВЛог_ФайлеЗапускаПродуктаОтсутствуетСтрока"); + + Возврат ВсеШаги; +КонецФункции + + +// Реализация шагов + +//установил каталог проекта "tests\fixtures" как текущий +Процедура УстановилКаталогПроектаКакТекущий(Знач ПутьКаталога) Экспорт + УстановитьТекущийКаталог(ОбъединитьПути(КаталогПроекта(), ПутьКаталога)); +КонецПроцедуры + +//в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг" +Процедура ВЛог_ФайлеЗапускаПродуктаЕстьСтрока(Знач ПроверяемаяСтрока) Экспорт + ТекстЛогФайла = БДД.ПолучитьИзКонтекста("ТекстЛогФайлаПродукта"); + Если СтрЧислоСтрок(ПроверяемаяСтрока) = 1 Тогда + Ожидаем.Что(ТекстЛогФайла).Содержит(ПроверяемаяСтрока); + Иначе + ПроверитьЧтоМногострочнаяСтрокаСодержитПодстрокуБезУчетаНачальныхКонечныхПробеловВПодстроках(ТекстЛогФайла, ПроверяемаяСтрока); + КонецЕсли; +КонецПроцедуры + +//TODO перенести в ассерты oscript-library +Процедура ПроверитьЧтоМногострочнаяСтрокаСодержитПодстрокуБезУчетаНачальныхКонечныхПробеловВПодстроках(Знач Строка, Знач Подстрока, ДопСообщениеОшибки = "") + СообщениеОшибки = ""; + Нашли = МногострочнаяСтрокаСодержитПодстрокуБезУчетаНачальныхКонечныхПробеловВПодстроках(Строка, Подстрока, СообщениеОшибки); + Если Не Нашли Тогда + ВызватьИсключение СтрШаблон("Ожидали, что в строке < + |%1 + |> + |найдем подстроку< + |%2 + |> + |А это не так. + |Уточнение: %3. + |%4", Строка, Подстрока, СообщениеОшибки, ДопСообщениеОшибки); + КонецЕсли; +КонецПроцедуры + +Функция МногострочнаяСтрокаСодержитПодстрокуБезУчетаНачальныхКонечныхПробеловВПодстроках(Знач Строка, Знач Подстрока, СообщениеОшибки = "") + ПерваяСтрока = СокрЛП(СтрПолучитьСтроку(Подстрока, 1)); + НашлиПервуюСтроку = Ложь; + Для Счетчик = 1 По СтрЧислоСтрок(Строка) Цикл + ОчереднаяСтрока = СокрЛП(СтрПолучитьСтроку(Строка, Счетчик)); + НашлиПервуюСтроку = Найти(ОчереднаяСтрока, ПерваяСтрока) <> 0; + Если НашлиПервуюСтроку Тогда + Прервать; + КонецЕсли; + КонецЦикла; + Если Не НашлиПервуюСтроку Тогда + СообщениеОшибки = СтрШаблон("Не нашли первую же подстроку <%1>", ПерваяСтрока); + Возврат Ложь; + КонецЕсли; + + СчетчикЧтоИщем = 2; + Для Счетчик = Счетчик+1 По СтрЧислоСтрок(Строка) Цикл + ОчереднаяСтрока = СокрЛП(СтрПолучитьСтроку(Строка, Счетчик)); + ЧтоИщем = СокрЛП(СтрПолучитьСтроку(Подстрока, СчетчикЧтоИщем)); + Поз = Найти(ОчереднаяСтрока, ЧтоИщем); + Если Поз = 0 Тогда + СообщениеОшибки = СтрШаблон("Не нашли подстроку № %1 <%2>", СчетчикЧтоИщем, ЧтоИщем); + Возврат Ложь; + Иначе + СчетчикЧтоИщем = СчетчикЧтоИщем + 1; + Если СчетчикЧтоИщем > СтрЧислоСтрок(Подстрока) Тогда + Возврат Истина; + КонецЕсли; + КонецЕсли; + КонецЦикла; + Возврат СчетчикЧтоИщем > СтрЧислоСтрок(Подстрока); +КонецФункции + +//в лог-файле запуска продукта отсутствует строка "ДоЭтогоШагаВыполнениеДойтиНеДолжно" +Процедура ВЛог_ФайлеЗапускаПродуктаОтсутствуетСтрока(Знач ПроверяемаяСтрока) Экспорт + ТекстЛогФайла = БДД.ПолучитьИзКонтекста("ТекстЛогФайлаПродукта"); + Ожидаем.Что(ТекстЛогФайла).ЭтоНе().Содержит(ПроверяемаяСтрока); +КонецПроцедуры + +Функция КаталогПроекта() Экспорт + КаталогПроекта = ОбъединитьПути(ТекущийСценарий().Каталог, "..", "..", ".."); + Возврат КаталогПроекта; +КонецФункции diff --git "a/features/core/step_definitions/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" "b/features/core/step_definitions/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" index ef1ad8f..18a019a 100644 --- "a/features/core/step_definitions/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" +++ "b/features/core/step_definitions/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" @@ -15,11 +15,11 @@ КонецФункции //Я сохранил значение 10 в исполнителе -Процедура ЯСохранилЗначениеВИсполнителе(Значение) Экспорт +Процедура ЯСохранилЗначениеВИсполнителе(Знач Значение) Экспорт СохраненноеЗначение = Значение; КонецПроцедуры //я получаю значение 10 от исполнителя -Процедура ЯПолучаюЗначениеОтИсполнителя(ЗначениеДляПроверки) Экспорт +Процедура ЯПолучаюЗначениеОтИсполнителя(Знач ЗначениеДляПроверки) Экспорт Ожидаем.Что(СохраненноеЗначение).Равно(ЗначениеДляПроверки); КонецПроцедуры diff --git "a/features/core/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" "b/features/core/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" index 3001b30..966d39e 100644 --- "a/features/core/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" +++ "b/features/core/step_definitions/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" @@ -32,19 +32,19 @@ КонецФункции //я передаю параметр 11.02.2010 -Процедура ЯПередаюПараметр(Парам) Экспорт +Процедура ЯПередаюПараметр(Знач Парам) Экспорт ДобавитьВЖурнал("ЯПередаюПараметр", Парам); ИсходныйПараметр = Парам; ТипИсходногоПараметра = ТипЗнч(Парам); КонецПроцедуры //я получаю параметр "Минимальный" -Процедура ЯПолучаюПараметр(ЗначениеПараметра) Экспорт +Процедура ЯПолучаюПараметр(Знач ЗначениеПараметра) Экспорт Ожидаем.Что(ЗначениеПараметра, "Ожидаем, что первым шагом был передан правильный параметр, а это не так").Равно(ИсходныйПараметр); КонецПроцедуры //я получаю параметр с типом "Дата" -Процедура ЯПолучаюПараметрСТипом(СтрокаТип) Экспорт +Процедура ЯПолучаюПараметрСТипом(Знач СтрокаТип) Экспорт ДобавитьВЖурнал("ЯПолучаюПараметрСТипом", СтрокаТип); Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", ИсходныйПараметр, ТипИсходногоПараметра)).Равно(""+ТипИсходногоПараметра); @@ -56,21 +56,17 @@ КонецПроцедуры //количество строк у параметра равно 2 -Процедура КоличествоСтрокУПараметраРавно(ЧислоСтрок) Экспорт +Процедура КоличествоСтрокУПараметраРавно(Знач ЧислоСтрок) Экспорт Ожидаем.Что(СтрЧислоСтрок(ИсходныйПараметр), "СтрЧислоСтрок(ИсходныйПараметр)").Равно(ЧислоСтрок); КонецПроцедуры //1 строка у параметра равна "первая строка" -Процедура СтрокаУПараметраРавна(НомерСтроки, СтрокаПоНомеру) Экспорт - ОжидаемаяСтрока = "первая строка"; - Если НомерСтроки = 2 Тогда - ОжидаемаяСтрока = "вторая строка"; - КонецЕсли; +Процедура СтрокаУПараметраРавна(Знач НомерСтроки, Знач ОжидаемаяСтрока) Экспорт Ожидаем.Что(СтрПолучитьСтроку(ИсходныйПараметр, НомерСтроки), "СтрПолучитьСтроку(ИсходныйПараметр, НомерСтроки)").Равно(ОжидаемаяСтрока); КонецПроцедуры //я передаю два параметра разных типов 1 и "Строка1" -Процедура ЯПередаюДваПараметраРазныхТиповИ(Парам1, Парам2) Экспорт +Процедура ЯПередаюДваПараметраРазныхТиповИ(Знач Парам1, Знач Парам2) Экспорт ИсходныйПараметр = Парам1; ТипИсходногоПараметра = ТипЗнч(Парам1); ИсходныйПараметр2 = Парам2; @@ -78,25 +74,25 @@ КонецПроцедуры //я в первом параметре получаю значение с типом "Строка" -Процедура ЯВПервомПараметреПолучаюЗначениеСТипом(СтрокаТип) Экспорт +Процедура ЯВПервомПараметреПолучаюЗначениеСТипом(Знач СтрокаТип) Экспорт Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", ИсходныйПараметр, ТипИсходногоПараметра)).Равно(""+ТипИсходногоПараметра); КонецПроцедуры //я в втором параметре получаю значение с типом Число" -Процедура ЯВВторомПараметреПолучаюЗначениеСТипом(СтрокаТип) Экспорт +Процедура ЯВВторомПараметреПолучаюЗначениеСТипом(Знач СтрокаТип) Экспорт Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", ИсходныйПараметр2, ТипИсходногоПараметра2)).Равно(""+ТипИсходногоПараметра2); КонецПроцедуры //я в первом параметре получаю значение 1 -Процедура ЯВПервомПараметреПолучаюЗначение(Парам1) Экспорт +Процедура ЯВПервомПараметреПолучаюЗначение(Знач Парам1) Экспорт Ожидаем.Что(Парам1, СтрШаблон("Ожидаем, что был передан параметр %1, а это не так", ИсходныйПараметр)).Равно(ИсходныйПараметр); КонецПроцедуры //я в втором параметре получаю значение "Строка1" -Процедура ЯВВторомПараметреПолучаюЗначение(Парам1) Экспорт +Процедура ЯВВторомПараметреПолучаюЗначение(Знач Парам1) Экспорт Ожидаем.Что(Парам1, СтрШаблон("Ожидаем, что был передан параметр %1, а это не так", ИсходныйПараметр2)).Равно(ИсходныйПараметр2); КонецПроцедуры diff --git "a/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" "b/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" index b43ce40..658e59a 100644 --- "a/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" +++ "b/features/core/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.os" @@ -1,5 +1,7 @@ #Использовать logos +#Использовать "../../.." + Перем Лог; Перем БДД; @@ -25,6 +27,7 @@ ВсеШаги.Добавить("ЯПодставилФайлШаговСУжеРеализованнымиШагамиДляФичи"); ВсеШаги.Добавить("ЯЗапустилВыполнениеФичиСПередачейПараметра"); ВсеШаги.Добавить("ЯСоздалФайлФичиСТекстом"); + ВсеШаги.Добавить("ЯСоздалФайлСТекстом"); ВсеШаги.Добавить("ЯСоздалЕщеОдинКаталог"); ВсеШаги.Добавить("УстановилКаталогКакТекущий"); ВсеШаги.Добавить("ЯЗапустилВыполнениеФичи"); @@ -50,7 +53,7 @@ КонецПроцедуры //я подготовил специальную тестовую фичу "ПередачаПараметров" -Процедура ЯПодготовилСпециальнуюТестовуюФичу(ИмяФичи) Экспорт +Процедура ЯПодготовилСпециальнуюТестовуюФичу(Знач ИмяФичи) Экспорт ФайлИсходнойФичи = ПолучитьФайлИсходнойФичи(ИмяФичи); @@ -68,18 +71,17 @@ Ожидаем.Что(ФайлИсполнителя.Существует(), "Ожидаем, что скрипт исполнителя шагов существует, а его нет. "+ФайлИсполнителя.ПолноеИмя).Равно(Истина); ФайлФичиИлиКаталога = Новый Файл(ОбъединитьПути(ТекущийКаталог(), ИмяФичи + ".feature")); - ИмяЛогаКоманды = ОбъединитьПути(ТекущийКаталог(), "gen-log.txt"); - СтрокаКоманды = СтрШаблон("cmd /c oscript.exe %4 %1 gen %2 %3 %5", ПутьИсполнителяБДД, ФайлФичиИлиКаталога.ПолноеИмя, - ПараметрыКоманднойСтроки, "-encoding=utf-8", СуффиксПеренаправленияВывода(ИмяЛогаКоманды, Ложь)); + СтрокаКоманды = СтрШаблон("oscript.exe %4 %1 gen %2 %3", ПутьИсполнителяБДД, ФайлФичиИлиКаталога.ПолноеИмя, + ПараметрыКоманднойСтроки, "-encoding=utf-8"); - Лог.Отладка("СтрокаКоманды "+СтрокаКоманды); + ТекстФайла = ""; + КодВозврата = ВыполнитьПроцесс(СтрокаКоманды, ТекстФайла); - КодВозврата = Неопределено; - ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог(), Истина, КодВозврата); + БДД.СохранитьВКонтекст("ТекстЛогФайлаПродукта", ТекстФайла); - Если КодВозврата <> 0 Тогда - ВывестиТекстФайла(ИмяЛогаКоманды); + Если КодВозврата <> 0 ИЛИ СтрНайти(ПараметрыКоманднойСтроки, "-verbose on") <> 0 Тогда + ВывестиТекст(ТекстФайла); Ожидаем.Что(КодВозврата, "Ожидаем, что код возврата равен 0, а это не так").Равно(0); КонецЕсли; @@ -92,19 +94,19 @@ //я получил сгенерированный os-файл "ФичаБезШагов" в ожидаемом каталоге Процедура ЯПолучилСгенерированныйOs_ФайлВОжидаемомКаталоге(Знач ИмяФичи) Экспорт - ФайлШагов = Новый Файл(ОбъединитьПути(ТекущийКаталог(), "step_definitions", ИмяФичи+".os")); - Ожидаем.Что(ФайлШагов.Существует(), "Ожидаем, что файл исполнителя шагов существует, а его нет. "+ФайлШагов.ПолноеИмя).Равно(Истина); + ФайлШагов = Новый Файл(ОбъединитьПути(ТекущийКаталог(), "step_definitions", ИмяФичи+".os")); + Ожидаем.Что(ФайлШагов.Существует(), "Ожидаем, что файл исполнителя шагов существует, а его нет. "+ФайлШагов.ПолноеИмя).Равно(Истина); КонецПроцедуры //я не получил сгенерированный os-файл "ФичаБезШагов" в ожидаемом каталоге Процедура ЯНеПолучилСгенерированныйOs_ФайлВОжидаемомКаталоге(Знач ИмяФичи) Экспорт - ФайлШагов = Новый Файл(ОбъединитьПути(ТекущийКаталог(), "step_definitions", ИмяФичи+".os")); - Ожидаем.Что(ФайлШагов.Существует(), "Ожидаем, что файл исполнителя шагов не существует, а он есть. "+ФайлШагов.ПолноеИмя).Равно(Ложь); + ФайлШагов = Новый Файл(ОбъединитьПути(ТекущийКаталог(), "step_definitions", ИмяФичи+".os")); + Ожидаем.Что(ФайлШагов.Существует(), "Ожидаем, что файл исполнителя шагов не существует, а он есть. "+ФайлШагов.ПолноеИмя).Равно(Ложь); КонецПроцедуры //проверка поведения фичи "ПередачаПараметров" закончилась со статусом "НеРеализован" -Процедура ПроверкаПоведенияФичиЗакончиласьСоСтатусом(ИмяФичи, ОжидаемыйСтатусВыполненияСтрока) Экспорт - ИсполнительБДД = ЗагрузитьСценарий(ОбъединитьПути(ПолучитьКаталогИсходников(), "bdd-exec.os")); +Процедура ПроверкаПоведенияФичиЗакончиласьСоСтатусом(Знач ИмяФичи, Знач ОжидаемыйСтатусВыполненияСтрока) Экспорт + ИсполнительБДД = Новый ИсполнительБДД; ОжидаемыйСтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения()[ОжидаемыйСтатусВыполненияСтрока]; @@ -144,20 +146,61 @@ ФайлФичиИлиКаталога = Новый Файл(ИмяФичиИлиПутьКаталога + ".feature"); КонецЕсли; - ИмяЛогаКоманды = ОбъединитьПути(ТекущийКаталог(), "exec-log.txt"); - СтрокаКоманды = СтрШаблон("cmd /c oscript.exe %4 %1 %2 %3 %5", ПутьИсполнителяБДД, ФайлФичиИлиКаталога.ПолноеИмя, - СохраненныеПараметрыКоманднойСтроки, "-encoding=utf-8", СуффиксПеренаправленияВывода(ИмяЛогаКоманды, Ложь)); - Лог.Отладка("СтрокаКоманды "+СтрокаКоманды); + СтрокаКоманды = СтрШаблон("oscript.exe %4 %1 %2 %3 %5", ПутьИсполнителяБДД, ФайлФичиИлиКаталога.ПолноеИмя, + СохраненныеПараметрыКоманднойСтроки, "-encoding=utf-8"); + + ТекстФайла = ""; + КодВозврата = ВыполнитьПроцесс(СтрокаКоманды, ТекстФайла); - КодВозврата = Неопределено; - ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог(), Истина, КодВозврата); + БДД.СохранитьВКонтекст("ТекстЛогФайлаПродукта", ТекстФайла); - Если КодВозврата <> ОжидаемыйКодВозврата Тогда - ВывестиТекстФайла(ИмяЛогаКоманды); - Ожидаем.Что(КодВозврата, "ПроверитьПоведениеФичиИлиКаталога").Равно(ОжидаемыйКодВозврата); + Если КодВозврата <> ОжидаемыйКодВозврата ИЛИ СтрНайти(ПараметрыКоманднойСтроки, "-verbose on") <> 0 Тогда + ВывестиТекст(ТекстФайла); + Ожидаем.Что(КодВозврата, "Код возврата в ПроверитьПоведениеФичиИлиКаталога").Равно(ОжидаемыйКодВозврата); КонецЕсли; КонецПроцедуры +Функция ВыполнитьПроцесс(Знач СтрокаВыполнения, ТекстВывода, Знач КодировкаПотока = Неопределено) + Перем ПаузаОжиданияЧтенияБуфера; + + ПаузаОжиданияЧтенияБуфера = 10; + МаксСчетчикЦикла = 100000; + + Если КодировкаПотока = Неопределено Тогда + КодировкаПотока = КодировкаТекста.UTF8; + КонецЕсли; + Лог.Отладка("СтрокаКоманды "+СтрокаВыполнения); + Процесс = СоздатьПроцесс(СтрокаВыполнения, ТекущийКаталог(), Истина,Истина, КодировкаПотока); + Процесс.Запустить(); + + ТекстВывода = ""; + Счетчик = 0; + + Пока Не Процесс.Завершен Цикл + Текст = Процесс.ПотокВывода.Прочитать(); + Лог.Отладка("Цикл ПотокаВывода "+Текст); + Если Текст = Неопределено ИЛИ ПустаяСтрока(Текст) Тогда + Прервать; + КонецЕсли; + ТекстВывода = ТекстВывода + Текст; + + Счетчик = Счетчик + 1; + Если Счетчик > МаксСчетчикЦикла Тогда + Прервать; + КонецЕсли; + + sleep(ПаузаОжиданияЧтенияБуфера); + КонецЦикла; + + Процесс.ОжидатьЗавершения(); + + Текст = Процесс.ПотокВывода.Прочитать(); + ТекстВывода = ТекстВывода + Текст; + Лог.Отладка(ТекстВывода); + + Возврат Процесс.КодВозврата; +КонецФункции + //я запустил выполнение фичи "ФичаБезШагов" с передачей параметра "-require СтруктураСценария.feature" Процедура ЯЗапустилВыполнениеФичиСПередачейПараметра(Знач ИмяФичи, Знач ПараметрыКоманднойСтроки) Экспорт СохраненныеПараметрыКоманднойСтроки = ПараметрыКоманднойСтроки; @@ -169,7 +212,7 @@ КонецПроцедуры //я подставил файл шагов с уже реализованными шагами для фичи "ПередачаПараметров"() -Процедура ЯПодставилФайлШаговСУжеРеализованнымиШагамиДляФичи(ИмяФичи) Экспорт +Процедура ЯПодставилФайлШаговСУжеРеализованнымиШагамиДляФичи(Знач ИмяФичи) Экспорт ИмяИсполнителяШагов = ФайлИсходнойФичи.ИмяБезРасширения+ ".os"; ИсходныйФайлИсполнителяШагов = Новый Файл(ОбъединитьПути(ФайлИсходнойФичи.Путь, "step_definitions", ИмяИсполнителяШагов )); ФайлИсполнителяШагов = Новый Файл(ОбъединитьПути(ФайлФичи.Путь, "step_definitions", ИмяИсполнителяШагов )); @@ -182,19 +225,36 @@ //установил тестовый каталог как текущий Процедура УстановилТестовыйКаталогКакТекущий() Экспорт - УстановитьТекущийКаталог(ВременныйКаталогФичи.ПолноеИмя); + УстановитьТекущийКаталог(ВременныйКаталогФичи.ПолноеИмя); КонецПроцедуры //я создал еще один каталог "lib" -Процедура ЯСоздалЕщеОдинКаталог(ИмяКаталога) Экспорт - СоздатьКаталог(ОбъединитьПути(ВременныйКаталогФичи.ПолноеИмя, ИмяКаталога)); +Процедура ЯСоздалЕщеОдинКаталог(Знач ИмяКаталога) Экспорт + СоздатьКаталог(ОбъединитьПути(ВременныйКаталогФичи.ПолноеИмя, ИмяКаталога)); КонецПроцедуры //установил каталог "lib" как текущий -Процедура УстановилКаталогКакТекущий(ИмяКаталога) Экспорт +Процедура УстановилКаталогКакТекущий(Знач ИмяКаталога) Экспорт УстановитьТекущийКаталог(ОбъединитьПути(ВременныйКаталогФичи.ПолноеИмя, ИмяКаталога)); КонецПроцедуры + +//я создал файл "ПустойСкрипт.os" с текстом +//""" +//// Пустой скрипт +//""" +Процедура ЯСоздалФайлСТекстом(Знач ПутьФайла, Знач ТексФайла) Экспорт + ЗаписьФайла = Новый ЗаписьТекста(ОбъединитьПути(ТекущийКаталог(), ПутьФайла), "utf-8"); + + Для Счетчик = 1 По СтрЧислоСтрок(ТексФайла) Цикл + Строка = СтрПолучитьСтроку(ТексФайла, Счетчик); + ЗаписьФайла.ЗаписатьСтроку(Строка); + //Лог.Отладка("Записываю в файл шагов ----- "+Строка); + КонецЦикла; + + ЗаписьФайла.Закрыть(); +КонецПроцедуры + //я создал файл фичи "ФичаБезШагов" с текстом //""" //# language: ru @@ -204,15 +264,7 @@ // Тогда я получаю параметр "Минимальный" //""" Процедура ЯСоздалФайлФичиСТекстом(Знач ИмяФичи, Знач ТекстФичи) Экспорт - ЗаписьФайла = Новый ЗаписьТекста(ПутьВоВременномКаталоге(ИмяФичи + ".feature"), "utf-8"); - - Для Счетчик = 1 По СтрЧислоСтрок(ТекстФичи) Цикл - Строка = СтрПолучитьСтроку(ТекстФичи, Счетчик); - ЗаписьФайла.ЗаписатьСтроку(Строка); - //Лог.Отладка("Записываю в файл шагов ----- "+Строка); - КонецЦикла; - - ЗаписьФайла.Закрыть(); + ЯСоздалФайлСТекстом(ПутьВоВременномКаталоге(ИмяФичи + ".feature"), ТекстФичи); КонецПроцедуры Функция ПолучитьТестовыйФайлФичи(ИмяФичи) @@ -236,12 +288,12 @@ Ожидаем.Что(ФайлИсполнителяШагов.Существует(), "Ожидаем, что файл исполнителя шагов не существует, а он есть. "+ФайлИсполнителяШагов.ПолноеИмя).Равно(Ложь); КонецПроцедуры -Процедура ВывестиТекстФайла(Знач ИмяФайла, Знач Кодировка = Неопределено) +Функция ПолучитьТекстФайла(Знач ИмяФайла, Знач Кодировка = Неопределено) Файл = Новый Файл(ИмяФайла); Если НЕ Файл.Существует() Тогда Лог.Информация("Не существует лог-файл <"+ИмяФайла+">"); - Возврат; + Возврат ""; КонецЕсли; Если Кодировка = Неопределено Тогда @@ -252,9 +304,15 @@ СтрокаФайла = ЧТ.Прочитать(); ЧТ.Закрыть(); + Возврат СтрокаФайла; + +КонецФункции + +Процедура ВывестиТекст(Знач Строка) + Лог.Информация(""); Лог.Информация(" ---------------- ---------------- ---------------- "); - Лог.Информация(СтрокаФайла); + Лог.Информация( Строка ); Лог.Информация(" ---------------- ---------------- ---------------- "); Лог.Информация(""); @@ -269,11 +327,11 @@ Возврат ОбъединитьПути(КаталогПроекта, "src"); КонецФункции // ПолучитьКаталогИсходников() -Функция ПолучитьФайлИсходнойФичи(ИмяФичи) +Функция ПолучитьФайлИсходнойФичи(Знач ИмяФичи) Возврат Новый Файл(ОбъединитьПути(ТекущийСценарий().Каталог, "..", ИмяФичи+".feature")); КонецФункции // ПолучитьФайлИсходнойФичи() -Функция ПутьВоВременномКаталоге(ИмяФайла) +Функция ПутьВоВременномКаталоге(Знач ИмяФайла) Возврат ОбъединитьПути(ВременныйКаталогФичи.ПолноеИмя, ИмяФайла); КонецФункции // ПутьВоВременномКаталоге(ИмяФайла) diff --git "a/features/core/step_definitions/\320\237\321\200\320\276\320\263\320\276\320\275\320\222\321\201\320\265\321\205\320\244\320\270\321\207\320\237\321\200\320\276\320\265\320\272\321\202\320\260.os" "b/features/core/step_definitions/\320\237\321\200\320\276\320\263\320\276\320\275\320\222\321\201\320\265\321\205\320\244\320\270\321\207\320\237\321\200\320\276\320\265\320\272\321\202\320\260.os" deleted file mode 100644 index 5a134cb..0000000 --- "a/features/core/step_definitions/\320\237\321\200\320\276\320\263\320\276\320\275\320\222\321\201\320\265\321\205\320\244\320\270\321\207\320\237\321\200\320\276\320\265\320\272\321\202\320\260.os" +++ /dev/null @@ -1,75 +0,0 @@ -#Использовать logos - -Перем Лог; -Перем БДД; - -Перем ПомощникТестирования; -Перем НаборФичКаталогаПроекта; - -Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт - БДД = КонтекстФреймворкаBDD; - - ВсеШаги = Новый Массив; - - ВсеШаги.Добавить("ЯВыполнилПодключениеТестовогоСкрипта"); - ВсеШаги.Добавить("ЯПолучилНаборФичИзКаталогаФичПроектаИсключаяТекущуюФичу"); - ВсеШаги.Добавить("УстановилКаталогаФичПроектаКакТекущий"); - ВсеШаги.Добавить("ПроверкаПоведенияКаждойФичиИзНабораФичЗакончиласьСКодомВозврата"); - - Возврат ВсеШаги; -КонецФункции - -//я выполнил подключение тестового скрипта "ПроверкаГенерации" -Процедура ЯВыполнилПодключениеТестовогоСкрипта(ИмяСкрипта) Экспорт - ПомощникТестирования = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, ИмяСкрипта+".os")); - - ДопЛог = Логирование.ПолучитьЛог(ПомощникТестирования.ИмяЛога()); - ДопЛог.УстановитьУровень(Лог.Уровень()); -КонецПроцедуры - -//я получил набор фич из каталога фич проекта исключая текущую фичу -Процедура ЯПолучилНаборФичИзКаталогаФичПроектаИсключаяТекущуюФичу() Экспорт - НаборФичКаталогаПроекта = НайтиФайлы(КаталогФич().ПолноеИмя, "*.feature"); - ФайлТекущегоСценария = Новый Файл(ТекущийСценарий().Источник); - Номер = -1; - Для каждого ФайлФичи Из НаборФичКаталогаПроекта Цикл - Номер = Номер + 1; - Если ФайлФичи.ИмяБезРасширения = ФайлТекущегоСценария.ИмяБезРасширения Тогда - НаборФичКаталогаПроекта.Удалить(Номер); - Прервать; - КонецЕсли; - КонецЦикла; -КонецПроцедуры - -//проверка поведения каждой фичи из набора фич закончилась с кодом возврата 0 -Процедура ПроверкаПоведенияКаждойФичиИзНабораФичЗакончиласьСКодомВозврата(ОжидаемыйКодВозврата) Экспорт - МассивОшибочныхФич = Новый Массив; - Для каждого ФайлФичи Из НаборФичКаталогаПроекта Цикл - ИмяФичи = ФайлФичи.ИмяБезРасширения; - Лог.Информация("Проверяю фичу "+ИмяФичи); - Попытка - ПомощникТестирования.ПроверкаПоведенияФичиЗакончиласьСКодомВозврата(ИмяФичи, ОжидаемыйКодВозврата); - Исключение - МассивОшибочныхФич.Добавить(ИмяФичи); - КонецПопытки; - КонецЦикла; - Если ЗначениеЗаполнено(МассивОшибочныхФич) Тогда - Лог.Информация("Ошибочные фичи:"); - Для каждого ИмяФичи Из МассивОшибочныхФич Цикл - Лог.Информация("Фича - "+ИмяФичи); - КонецЦикла; - ВызватьИсключение "Есть упавшие фичи"; - КонецЕсли; -КонецПроцедуры - -//установил каталога фич проекта как текущий -Процедура УстановилКаталогаФичПроектаКакТекущий() Экспорт - УстановитьТекущийКаталог(КаталогФич().ПолноеИмя); -КонецПроцедуры - -Функция КаталогФич() - Возврат Новый Файл(ОбъединитьПути(ТекущийСценарий().Каталог, "..")); -КонецФункции // КаталогФич() - -Лог = Логирование.ПолучитьЛог("bdd.ВыполнениеФич.feature"); -//Лог.УстановитьУровень(УровниЛога.Отладка); diff --git "a/features/core/step_definitions/\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\321\213\320\271\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" "b/features/core/step_definitions/\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\321\213\320\271\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" new file mode 100644 index 0000000..9b9fd96 --- /dev/null +++ "b/features/core/step_definitions/\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\321\213\320\271\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.os" @@ -0,0 +1,39 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯСохранилКлючИЗначениеВПрограммномКонтексте"); + ВсеШаги.Добавить("ЯПолучаюКлючИЗначениеИзПрограммногоКонтекста"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//Я сохранил ключ "Ключ1" и значение 10 в программном контексте +Процедура ЯСохранилКлючИЗначениеВПрограммномКонтексте(Знач Ключ, Знач Значение) Экспорт + БДД.СохранитьВКонтекст(Ключ, Значение); +КонецПроцедуры + +//я получаю ключ "Ключ1" и значение 10 из программного контекста +Процедура ЯПолучаюКлючИЗначениеИзПрограммногоКонтекста(Знач Ключ, Знач ОжидаемоеЗначение) Экспорт + НовоеЗначение = БДД.ПолучитьИзКонтекста(Ключ); + Ожидаем.Что(НовоеЗначение).Равно(ОжидаемоеЗначение); +КонецПроцедуры + diff --git "a/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" "b/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" index fad619c..2393bc9 100644 --- "a/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" +++ "b/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" @@ -13,11 +13,11 @@ Возврат ВсеШаги; КонецФункции -Процедура ЯНичегоНеДелаю(ПарамСтрока) Экспорт +Процедура ЯНичегоНеДелаю(Знач ПарамСтрока) Экспорт ДобавитьВЖурнал("ЯНичегоНеДелаю", ПарамСтрока); КонецПроцедуры -Процедура НичегоНеПроисходит(ДругойПарамСтрока) Экспорт +Процедура НичегоНеПроисходит(Знач ДругойПарамСтрока) Экспорт ДобавитьВЖурнал("НичегоНеПроисходит", ДругойПарамСтрока); КонецПроцедуры diff --git "a/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" "b/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" index 9fea2fd..bc5eeaf 100644 --- "a/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" +++ "b/features/core/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" @@ -15,19 +15,19 @@ Возврат ВсеШаги; КонецФункции -Процедура ЯНичегоНеДелаю(ПарамСтрока) Экспорт +Процедура ЯНичегоНеДелаю(Знач ПарамСтрока) Экспорт ДобавитьВЖурнал("ЯНичегоНеДелаю", ПарамСтрока); КонецПроцедуры -Процедура НичегоНеПроисходит(ДругойПарамСтрока) Экспорт +Процедура НичегоНеПроисходит(Знач ДругойПарамСтрока) Экспорт ДобавитьВЖурнал("НичегоНеПроисходит", ДругойПарамСтрока); КонецПроцедуры -Процедура ВсеПутемИ(Парам1, Парам2) Экспорт +Процедура ВсеПутемИ(Знач Парам1, Знач Парам2) Экспорт ДобавитьВЖурнал("ВсеПутемИ", Парам1, Парам2); КонецПроцедуры -Процедура НиктоНичегоНеДелает(Парам1) Экспорт +Процедура НиктоНичегоНеДелает(Знач Парам1) Экспорт ДобавитьВЖурнал("НиктоНичегоНеДелает", Парам1); КонецПроцедуры diff --git "a/features/core/step_definitions/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217.os" "b/features/core/step_definitions/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217.os" index e5fd7b0..870b4de 100644 --- "a/features/core/step_definitions/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217.os" +++ "b/features/core/step_definitions/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260\320\241\321\206\320\265\320\275\320\260\321\200\320\270\321\217.os" @@ -21,7 +21,7 @@ КонецФункции //я передаю два параметра разных типов <Параметр> и 1 -Процедура ЯПередаюДваПараметраРазныхТиповИ(ПарамСтрока1, ПарамЧисло2) Экспорт +Процедура ЯПередаюДваПараметраРазныхТиповИ(Знач ПарамСтрока1, Знач ПарамЧисло2) Экспорт //Сообщить(СтрШаблон("ПарамСтрока1 %1, ПарамЧисло2 %2", ПарамСтрока1, ПарамЧисло2)); ИсходныйПараметр = ПарамСтрока1; ТипИсходногоПараметра = ТипЗнч(ПарамСтрока1); @@ -30,25 +30,25 @@ КонецПроцедуры //я в первом параметре получаю значение с типом "Строка" -Процедура ЯВПервомПараметреПолучаюЗначениеСТипом(СтрокаТип) Экспорт +Процедура ЯВПервомПараметреПолучаюЗначениеСТипом(Знач СтрокаТип) Экспорт Ожидаем.Что(""+СтрокаТип, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", ИсходныйПараметр, ТипИсходногоПараметра)).Равно(""+ТипИсходногоПараметра); КонецПроцедуры //я в втором параметре получаю значение с типом Число" -Процедура ЯВВторомПараметреПолучаюЗначениеСТипом(СтрокаЧисло) Экспорт +Процедура ЯВВторомПараметреПолучаюЗначениеСТипом(Знач СтрокаЧисло) Экспорт Ожидаем.Что(""+СтрокаЧисло, СтрШаблон("Ожидаем, что был передан параметр %1 с типом %2, а это не так", ИсходныйПараметр2, ТипИсходногоПараметра2)).Равно(""+ТипИсходногоПараметра2); КонецПроцедуры //я в первом параметре получаю значение "Значение с пробелом" -Процедура ЯВПервомПараметреПолучаюЗначение(Парам1) Экспорт +Процедура ЯВПервомПараметреПолучаюЗначение(Знач Парам1) Экспорт Ожидаем.Что(Парам1, СтрШаблон("Ожидаем, что был передан параметр %1, а это не так", ИсходныйПараметр)).Равно(ИсходныйПараметр); КонецПроцедуры //я в втором параметре получаю значение 1 -Процедура ЯВВторомПараметреПолучаюЗначение(Парам1) Экспорт +Процедура ЯВВторомПараметреПолучаюЗначение(Знач Парам1) Экспорт Ожидаем.Что(Парам1, СтрШаблон("Ожидаем, что был передан параметр %1, а это не так", ИсходныйПараметр2)).Равно(ИсходныйПараметр2); КонецПроцедуры diff --git "a/features/core/step_definitions/\320\242\320\260\320\261\320\273\320\270\321\206\321\213\320\224\320\260\320\275\320\275\321\213\321\205.os" "b/features/core/step_definitions/\320\242\320\260\320\261\320\273\320\270\321\206\321\213\320\224\320\260\320\275\320\275\321\213\321\205.os" new file mode 100644 index 0000000..c0b7a6b --- /dev/null +++ "b/features/core/step_definitions/\320\242\320\260\320\261\320\273\320\270\321\206\321\213\320\224\320\260\320\275\320\275\321\213\321\205.os" @@ -0,0 +1,61 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯПередаюТаблицу"); + ВсеШаги.Добавить("ПереданнаяТаблицаЯвляетсяТипом"); + ВсеШаги.Добавить("УПереданнойТаблицыКолонки"); + ВсеШаги.Добавить("УПереданнойТаблицыСтроки"); + ВсеШаги.Добавить("УСтрокиТаблицыЗаданыЗначенияИ"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//я передаю таблицу +Процедура ЯПередаюТаблицу(Знач ИсходнаяТаблица) Экспорт + БДД.СохранитьВКонтекст("ТаблицаДанных", ИсходнаяТаблица); +КонецПроцедуры + +//переданная таблица является типом "ТаблицаЗначений" +Процедура ПереданнаяТаблицаЯвляетсяТипом(Знач ТипСтрокой) Экспорт + Таблица = БДД.ПолучитьИзКонтекста("ТаблицаДанных"); + Ожидаем.Что(Таблица).ИмеетТип(ТипСтрокой); +КонецПроцедуры + +//у переданной таблицы 2 колонки +Процедура УПереданнойТаблицыКолонки(Знач ОжидаемоеКоличество) Экспорт + Таблица = БДД.ПолучитьИзКонтекста("ТаблицаДанных"); + Ожидаем.Что(Таблица.Колонки).ИмеетДлину(ОжидаемоеКоличество); +КонецПроцедуры + +//у переданной таблицы 2 строки +Процедура УПереданнойТаблицыСтроки(Знач ОжидаемоеКоличество) Экспорт + Таблица = БДД.ПолучитьИзКонтекста("ТаблицаДанных"); + Ожидаем.Что(Таблица).ИмеетДлину(ОжидаемоеКоличество); +КонецПроцедуры + +//у 1 строки таблицы заданы значения "Ячейка11" и "Ячейка12" +Процедура УСтрокиТаблицыЗаданыЗначенияИ(Знач НомерСтроки, Знач ОжидаемоеЗначение0, Знач ОжидаемоеЗначение1) Экспорт + Таблица = БДД.ПолучитьИзКонтекста("ТаблицаДанных"); + СтрокаТаблицы = Таблица[НомерСтроки]; + Ожидаем.Что(СтрокаТаблицы[0], "СтрокаТаблицы[0]").Равно(ОжидаемоеЗначение0); + Ожидаем.Что(СтрокаТаблицы[1], "СтрокаТаблицы[1]").Равно(ОжидаемоеЗначение1); +КонецПроцедуры diff --git "a/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" index 8c2f309..a4b1790 100644 --- "a/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" +++ "b/features/core/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\244\320\270\321\207.feature" @@ -26,3 +26,50 @@ | с использованием полного пути каталога | КаталогТестовыйПолный | | с использованием относительного пути каталога | КаталогТестовыйОтносительный | +Сценарий: Выполнение фич в каталоге, в котором есть обычные os-скрипты, не являющиеся файлами шагов + Когда я подготовил тестовый каталог для фич + И установил тестовый каталог как текущий + И я создал файл "ПустойСкрипт.os" с текстом + """ + // Пустой скрипт + """ + + Тогда проверка поведения фич с передачей параметра "" из каталога "." закончилась с кодом возврата 0 + +Контекст: Каталог проекта устанавливаю как текущий + Допустим установил каталог проекта "tests\fixtures" как текущий + +Сценарий: После ошибочного шага следующие шаги сценария не выполняются + Тогда проверка поведения фичи "ПадающийШаг" закончилась с кодом возврата 2 + И в лог-файле запуска продукта есть строка "ЯЗапускаюПадающийШагСПараметром-Первый падающий шаг" + И в лог-файле запуска продукта отсутствует строка "ДоЭтогоШагаВыполнениеДойтиНеДолжно" + И в лог-файле запуска продукта есть строка "2 Шаг ( 0 Пройден, 0 Не реализован, 1 Сломался, 1 Не выполнялся )" + +Сценарий: Прогон фич из каталога при наличии падающих фич выдает правильный код возврата + Тогда проверка поведения фич с передачей параметра "" из каталога "." закончилась с кодом возврата 2 + +Сценарий: Проверка лога при запуске нереализованного шага сценария + Когда я подготовил тестовый каталог для фич + И установил тестовый каталог как текущий + И я создал файл фичи "НесуществующийШаг" с текстом + """ + # language: ru + Функционал: Просто функционал + Сценарий: Просто сценарий + Тогда выполняется несуществующий шаг + """ + + Тогда проверка поведения фичи "НесуществующийШаг" закончилась с кодом возврата 1 + И в лог-файле запуска продукта есть строка + """ + Функциональность Просто функционал + Сценарий Просто сценарий + выполняется несуществующий шаг + Не реализован + """ + И в лог-файле запуска продукта есть строка + """ + 1 Сценарий ( 0 Пройден, 1 Не реализован, 0 Сломался, 0 Не выполнялся ) + 1 Шаг ( 0 Пройден, 1 Не реализован, 0 Сломался, 0 Не выполнялся ) + + """ diff --git "a/features/core/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" "b/features/core/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" index c87c8ad..08b3534 100644 --- "a/features/core/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" +++ "b/features/core/\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" @@ -66,3 +66,10 @@ Тогда я получаю значение "НовоеЗначениеВКонтексте" от исполнителя +Контекст: Без начального шага + Простое описание контекста, которое приводило к зависанию + И Я сохранил значение "ЗначениеВКонтекстеШаг2" в исполнителе + +Сценарий: Первый сценарий + + Тогда я получаю значение "ЗначениеВКонтекстеШаг2" от исполнителя diff --git "a/features/core/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" "b/features/core/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" index f9245f3..7f90080 100644 --- "a/features/core/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" +++ "b/features/core/\320\237\320\265\321\200\320\265\320\264\320\260\321\207\320\260\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" @@ -35,12 +35,28 @@ Когда я передаю параметр """ первая строка + вторая строка """ Тогда я получаю параметр с типом "Строка" - И количество строк у параметра равно 2 + И количество строк у параметра равно 3 + И 1 строка у параметра равна "первая строка" + И 2 строка у параметра равна "" + И 3 строка у параметра равна "вторая строка" + +Сценарий: Использование многострочных строк, когда есть разное сочетание пробелов и табуляции + + Когда я передаю параметр + """ + первая строка + + вторая строка + """ + Тогда я получаю параметр с типом "Строка" + И количество строк у параметра равно 3 И 1 строка у параметра равна "первая строка" - И 2 строка у параметра равна "вторая строка" + И 2 строка у параметра равна "" + И 3 строка у параметра равна " вторая строка" Сценарий: Использование параметров разных типов в одном шаге diff --git "a/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.feature" "b/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.feature" index e03b217..c337ee3 100644 --- "a/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.feature" +++ "b/features/core/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\223\320\265\320\275\320\265\321\200\320\260\321\206\320\270\320\270.feature" @@ -4,12 +4,13 @@ Как Разработчик Я Хочу, чтобы у меня была возможность генерировать шаги в os-файлах для feature-файлов -Сценарий: Первичная генерация шагов - +Контекст: Тестовый каталог Когда я подготовил тестовый каталог для фич И установил тестовый каталог как текущий - # И я подготовил специальную тестовую фичу "ПередачаПараметров" - И я создал файл фичи "ФичаБезШагов" с текстом + +Сценарий: Первичная генерация шагов + + Когда я создал файл фичи "ФичаБезШагов" с текстом """ # language: ru Функционал: Библиотечные шаги @@ -17,16 +18,31 @@ Когда я передаю параметр "Минимальный" Тогда я получаю параметр "Минимальный" """ - И я запустил генерацию шагов фичи "ФичаБезШагов" + И я запустил генерацию шагов фичи "ФичаБезШагов" с передачей параметра "-verbose off" Тогда я получил сгенерированный os-файл "ФичаБезШагов" в ожидаемом каталоге И проверка поведения фичи "ФичаБезШагов" закончилась с кодом возврата 1 +Сценарий: Генерация шагов, если в представлении шагов есть сторонние символы-разделители + + Когда я создал файл фичи "Символы-Разделители" с текстом + """ + # language: ru + Функционал: Библиотечные шаги + Сценарий: Использование шагов из другой фичи + Когда я передаю символы-разделители .,;() + """ + И я запустил генерацию шагов фичи "Символы-Разделители" с передачей параметра "-verbose off" + Тогда я получил сгенерированный os-файл "Символы-Разделители" в ожидаемом каталоге + И проверка поведения фичи "Символы-Разделители" закончилась с кодом возврата 1 + Сценарий: Перегенерация шагов в случае существования файла шагов - Когда я подготовил тестовый каталог для фич - И установил тестовый каталог как текущий Когда я подготовил специальную тестовую фичу "ПередачаПараметров" И я подставил файл шагов с уже реализованными шагами для фичи "ПередачаПараметров" - И я запустил генерацию шагов фичи "ПередачаПараметров" + И я запустил генерацию шагов фичи "ПередачаПараметров" с передачей параметра "-verbose off" Тогда я получил сгенерированный os-файл "ПередачаПараметров" в ожидаемом каталоге И проверка поведения фичи "ПередачаПараметров" закончилась с кодом возврата 0 + #повторная перегенерация для проверки ошибок + И я запустил генерацию шагов фичи "ПередачаПараметров" с передачей параметра "-verbose off" + И я получил сгенерированный os-файл "ПередачаПараметров" в ожидаемом каталоге + И проверка поведения фичи "ПередачаПараметров" закончилась с кодом возврата 0 diff --git "a/features/core/\320\237\321\200\320\276\320\263\320\276\320\275\320\222\321\201\320\265\321\205\320\244\320\270\321\207\320\237\321\200\320\276\320\265\320\272\321\202\320\260.feature" "b/features/core/\320\237\321\200\320\276\320\263\320\276\320\275\320\222\321\201\320\265\321\205\320\244\320\270\321\207\320\237\321\200\320\276\320\265\320\272\321\202\320\260.feature" deleted file mode 100644 index ce19c0c..0000000 --- "a/features/core/\320\237\321\200\320\276\320\263\320\276\320\275\320\222\321\201\320\265\321\205\320\244\320\270\321\207\320\237\321\200\320\276\320\265\320\272\321\202\320\260.feature" +++ /dev/null @@ -1,12 +0,0 @@ -# language: ru - -Функционал: Выполнение фич - Как Разработчик - Я Хочу, чтобы у меня была возможность протестировать все фичи из каталога проекта - -Сценарий: Выполнение всех фич из каталога фич проекта - - Когда я выполнил подключение тестового скрипта "ПроверкаГенерации" - И я получил набор фич из каталога фич проекта исключая текущую фичу - И установил каталога фич проекта как текущий - Тогда проверка поведения каждой фичи из набора фич закончилась с кодом возврата 0 diff --git "a/features/core/\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\321\213\320\271\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" "b/features/core/\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\321\213\320\271\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" new file mode 100644 index 0000000..e0119cc --- /dev/null +++ "b/features/core/\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\321\213\320\271\320\232\320\276\320\275\321\202\320\265\320\272\321\201\321\202.feature" @@ -0,0 +1,14 @@ +# language: ru + +Функционал: Использование программного контекста + Как Разработчик + Я Хочу чтобы шаги разных сценариев могли обмениваться данными через програмнный контекст продукта + +Сценарий: Первый сценарий + + Когда Я сохранил ключ "Ключ1" и значение 10 в программном контексте + И я получаю ключ "Ключ1" и значение 10 из программного контекста + +Сценарий: Следующий сценарий + + Тогда я получаю ключ "Ключ1" и значение 10 из программного контекста diff --git "a/features/core/\320\242\320\260\320\261\320\273\320\270\321\206\321\213\320\224\320\260\320\275\320\275\321\213\321\205.feature" "b/features/core/\320\242\320\260\320\261\320\273\320\270\321\206\321\213\320\224\320\260\320\275\320\275\321\213\321\205.feature" new file mode 100644 index 0000000..a7d5268 --- /dev/null +++ "b/features/core/\320\242\320\260\320\261\320\273\320\270\321\206\321\213\320\224\320\260\320\275\320\275\321\213\321\205.feature" @@ -0,0 +1,16 @@ +# language: ru + +Функционал: Таблицы данных + Как Разработчик + Я Хочу чтобы можно было использовать различные форматы данных в фича-файлах + +Сценарий: Проверяю передачу простой таблицы + + Когда я передаю таблицу + | Ячейка11 | Ячейка12| + | Ячейка21 | Ячейка22| + Тогда переданная таблица является типом "ТаблицаЗначений" + И у переданной таблицы 2 колонки + И у переданной таблицы 2 строки + И у 0 строки таблицы заданы значения "Ячейка11" и "Ячейка12" + И у 1 строки таблицы заданы значения "Ячейка21" и "Ячейка22" \ No newline at end of file diff --git a/lib.config b/lib.config new file mode 100644 index 0000000..3369271 --- /dev/null +++ b/lib.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packagedef b/packagedef new file mode 100644 index 0000000..e0f89bd --- /dev/null +++ b/packagedef @@ -0,0 +1,7 @@ + +Описание.Имя("1bdd") + .Версия("0.9") + .ВключитьФайл("src") + .ВключитьФайл("tests") + .ВключитьФайл("features") + .ВключитьФайл("lib.config") \ No newline at end of file diff --git a/src/FileLineReader.os b/src/FileLineReader.os new file mode 100644 index 0000000..34b8943 --- /dev/null +++ b/src/FileLineReader.os @@ -0,0 +1,58 @@ +//---------------------------------------------------------- +//This Source Code Form is subject to the terms of the +//Mozilla Public License, v.2.0. If a copy of the MPL +//was not distributed with this file, You can obtain one +//at http://mozilla.org/MPL/2.0/. +//---------------------------------------------------------- + +////////////////////////////////////////////////////////////////// +// +// Объект-помощник для чтения файла фич +// +////////////////////////////////////////////////////////////////// + +Перем ЧтениеТекста; +Перем КоллекцияСтрок; +Перем ПозицияВКоллекции; + +//////////////////////////////////////////////////////////////////// +//{ Программный интерфейс + +Процедура Инициализировать(Знач ПутьФайла, Знач Кодировка = "UTF-8") Экспорт + КоллекцияСтрок = Новый Массив; + ПозицияВКоллекции = -1; + + ЧтениеТекста = Новый ЧтениеТекста(ПутьФайла, Кодировка); + ПрочитатьТекстВКоллекцию(); +КонецПроцедуры + +Процедура Закрыть() Экспорт + ЧтениеТекста.Закрыть(); +КонецПроцедуры + +Функция ПрочитатьСтроку() Экспорт + ПозицияВКоллекции = ПозицияВКоллекции + 1; + Если ПозицияВКоллекции >= КоллекцияСтрок.Количество() Тогда + Возврат Неопределено; + КонецЕсли; + + ОчереднаяСтрока = КоллекцияСтрок[ПозицияВКоллекции]; + Возврат ОчереднаяСтрока; +КонецФункции // ОчереднаяСтрока() + +Процедура ВернутьсяНаСтрокуНазад() Экспорт + ПозицияВКоллекции = ПозицияВКоллекции - 1; +КонецПроцедуры + +//} + +Процедура ПрочитатьТекстВКоллекцию() + Пока Истина Цикл + ОчереднаяСтрока = ЧтениеТекста.ПрочитатьСтроку(); + Если ОчереднаяСтрока = Неопределено Тогда + Прервать; + КонецЕсли; + КоллекцияСтрок.Добавить(ОчереднаяСтрока); + КонецЦикла; + +КонецПроцедуры \ No newline at end of file diff --git a/src/bdd-exec.os b/src/bdd-exec.os index cfa2401..854f281 100644 --- a/src/bdd-exec.os +++ b/src/bdd-exec.os @@ -15,6 +15,8 @@ #Использовать asserts #Использовать strings +// #Использовать ".." + Перем Лог; Перем ЧитательГеркин; @@ -26,9 +28,23 @@ Перем ТекущийУровень; +Перем Контекст; + //////////////////////////////////////////////////////////////////// //{ Программный интерфейс +//{ использование контекста внутри шагов сценариев + +// Параметры специально передаются без "Знач" для универсальности +Процедура СохранитьВКонтекст(Ключ, Значение) Экспорт + Контекст.Вставить(Ключ, Значение); +КонецПроцедуры + +Функция ПолучитьИзКонтекста(Знач Ключ) Экспорт + Возврат Контекст[Ключ]; +КонецФункции // ПолучитьИзКонтекста(Знач Ключ) Экспорт +// } + Функция ВыполнитьФичу(Знач ФайлФичи, Знач ФайлБиблиотек = Неопределено, Знач ИскатьВПодкаталогах = Истина) Экспорт НаборБиблиотечныхШагов = ПолучитьНаборБиблиотечныхШагов(ФайлБиблиотек); Лог.Отладка(СтрШаблон("Найдено библиотечных шагов: %1 шт.", ?(ЗначениеЗаполнено(НаборБиблиотечныхШагов), НаборБиблиотечныхШагов.Количество(), "0"))); @@ -56,7 +72,7 @@ Возврат РезультатыВыполнения; КонецФункции -Процедура ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения) Экспорт +Процедура ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения, Знач ПоказыватьИтогиФич) Экспорт МассивИтогов = Новый Массив; МассивИтогов.Добавить(ВозможныеТипыШагов.Функциональность); МассивИтогов.Добавить(ВозможныеТипыШагов.Сценарий); @@ -67,7 +83,7 @@ СтруктураИтогов.Вставить(Элем, СтатусыВыполненияДляПодсчета()); КонецЦикла; - РекурсивноПосчитатьИтогиВыполнения(РезультатыВыполнения.Строки[0], СтруктураИтогов); + РекурсивноПосчитатьИтогиВыполнения(РезультатыВыполнения, СтруктураИтогов); ИмяПоляИтога = "Итог"; Для каждого Итоги Из СтруктураИтогов Цикл @@ -80,7 +96,7 @@ Для каждого Элем Из МассивИтогов Цикл Итог = СтруктураИтогов[Элем]; ВыводимИтог = Истина; - Если Элем = ВозможныеТипыШагов.Функциональность И Итог[ИмяПоляИтога] = 1 Тогда + Если НЕ ПоказыватьИтогиФич И Элем = ВозможныеТипыШагов.Функциональность И Итог[ИмяПоляИтога] = 1 Тогда ВыводимИтог = Ложь; КонецЕсли; Если ВыводимИтог Тогда @@ -162,7 +178,7 @@ // В структуре есть поля // "Исполнитель" - объект-исполнитель шага (os-скрипт) // "Файл" - объект-файл с информацией о файле-исполнителе шага -Функция ПолучитЬМассивОписанийИсполнителяШагов(Знач ФайлБиблиотек) +Функция ПолучитьМассивОписанийИсполнителяШагов(Знач ФайлБиблиотек) МассивОписанийИсполнителяШагов = Новый Массив; Если Не ФайлБиблиотек.ЭтоКаталог() Тогда ОписаниеИсполнителяШагов = НайтиИсполнителяШагов(ФайлБиблиотек); @@ -199,7 +215,7 @@ НаборБиблиотечныхШагов = ДополнитьНаборШаговИзИсполнителяШаговФичи(ФайлСценария, НаборБиблиотечныхШагов); - РезультатыВыполнения.Строки[0].СтатусВыполнения = РекурсивноВыполнитьШаги(НаборБиблиотечныхШагов, РезультатыВыполнения.Строки[0]); + РезультатыВыполнения.Строки[0].СтатусВыполнения = РекурсивноВыполнитьШаги(ФайлСценария, НаборБиблиотечныхШагов, РезультатыВыполнения.Строки[0]); Возврат РезультатыВыполнения; КонецФункции @@ -230,8 +246,15 @@ Рефлектор = Новый Рефлектор; МассивПараметров = Новый Массив; МассивПараметров.Добавить(ЭтотОбъект); - МассивОписанийШагов = Рефлектор.ВызватьМетод(ИсполнительШагов, ЧитательГеркин.НаименованиеФункцииПолученияСпискаШагов(), МассивПараметров); - Возврат МассивОписанийШагов; + Попытка + МассивОписанийШагов = Рефлектор.ВызватьМетод(ИсполнительШагов, ЧитательГеркин.НаименованиеФункцииПолученияСпискаШагов(), МассивПараметров); + Возврат МассивОписанийШагов; + + Исключение + КонецПопытки; + + Возврат Новый Массив; + КонецФункции // ПолучитьМассивОписанийШагов() // возвращает Неопределено или структуру. @@ -266,7 +289,7 @@ Возврат ОписаниеИсполнителя; КонецФункции // ПолучитьИсполнителяШагов() -Функция РекурсивноВыполнитьШаги(Знач НаборБиблиотечныхШагов, Знач Узел) +Функция РекурсивноВыполнитьШаги(Знач ФайлСценария, Знач НаборБиблиотечныхШагов, Знач Узел) ТекущийУровень = Узел.Уровень(); ПредставлениеЛексемы = ?(Узел.ТипШага <> ВозможныеТипыШагов.Описание, Узел.Лексема +" ", ""); Если Узел.ТипШага <> ВозможныеТипыШагов.Шаг Тогда @@ -276,15 +299,29 @@ Лог.Отладка(СтрШаблон("Выполняю узел <%1>, адрес <%2>, тело <%3>", Узел.ТипШага, Узел.АдресШага, Узел.Тело)); СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; - СтатусВыполнения = ВыполнитьДействиеУзла(НаборБиблиотечныхШагов, Узел); - - Для Каждого СтрокаДерева Из Узел.Строки Цикл - НовыйСтатус = РекурсивноВыполнитьШаги(НаборБиблиотечныхШагов, СтрокаДерева); - СтатусВыполнения = ЗапомнитьСамоеХудшееСостояние(СтатусВыполнения, НовыйСтатус); - Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Пройден и СтрокаДерева.ТипШага = ВозможныеТипыШагов.Шаг Тогда - Прервать; + ХукВыполненУспешно = ВыполнитьХукУзла(ЧитательГеркин.ВозможныеХуки().ПередЗапускомСценария, ФайлСценария, Узел); + Если Не ХукВыполненУспешно Тогда + СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; + Иначе + + СтатусВыполнения = ВыполнитьДействиеУзла(НаборБиблиотечныхШагов, Узел); + + Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Сломался Тогда + Для Каждого СтрокаДерева Из Узел.Строки Цикл + НовыйСтатус = РекурсивноВыполнитьШаги(ФайлСценария, НаборБиблиотечныхШагов, СтрокаДерева); + СтатусВыполнения = ЗапомнитьСамоеХудшееСостояние(СтатусВыполнения, НовыйСтатус); + Если СтатусВыполнения <> ВозможныеСтатусыВыполнения.Пройден и СтрокаДерева.ТипШага = ВозможныеТипыШагов.Шаг Тогда + Прервать; + КонецЕсли; + КонецЦикла; КонецЕсли; - КонецЦикла; + КонецЕсли; + + ХукВыполненУспешно = ВыполнитьХукУзла(ЧитательГеркин.ВозможныеХуки().ПослеЗапускаСценария, ФайлСценария, Узел); + Если Не ХукВыполненУспешно Тогда + СтатусВыполнения = ВозможныеСтатусыВыполнения.Сломался; + КонецЕсли; + Узел.СтатусВыполнения = СтатусВыполнения; Если Узел.ТипШага <> ВозможныеТипыШагов.Шаг И Узел.ТипШага <> ВозможныеТипыШагов.Описание Тогда @@ -294,6 +331,45 @@ Возврат СтатусВыполнения; КонецФункции +Функция ВыполнитьХукУзла(Знач ОписаниеХука, Знач ФайлСценария, Знач Узел, Знач ПредставлениеШага = "") + Рез = Истина; + Если Узел.ТипШага = ОписаниеХука.ТипШага Тогда + АдресХука = ОписаниеХука.АдресШага; + ОписаниеИсполнителяШагов = НайтиИсполнителяШагов(ФайлСценария); + Если ОписаниеИсполнителяШагов <> Неопределено Тогда + Рефлектор = Новый Рефлектор; + + СтрокаПараметров = "Узел"; + МассивПараметров = Новый Массив; + МассивПараметров.Добавить(Узел); + + ИмяФайлаШагов = ОписаниеИсполнителяШагов.Файл.Имя; + Лог.Отладка(СтрШаблон(" Выполняю шаг <%1>, параметры <%2>, источник %3", + АдресХука, СтрокаПараметров, ИмяФайлаШагов)); + + Попытка + Рефлектор.ВызватьМетод(ОписаниеИсполнителяШагов.Исполнитель, АдресХука, МассивПараметров); + + Исключение + + Инфо = ИнформацияОбОшибке(); + текстОшибки = ПодробноеПредставлениеОшибки(Инфо); + + Если Инфо.Описание <> СтрШаблон("Метод объекта не обнаружен (%1)", АдресХука) Тогда + Рез = Ложь; + ПредставлениеШага = СтрШаблон("Не удалось выполнить хук <%1> для шага <%2> + |%3 + |%4", АдресХука, ИмяФайлаШагов, ПредставлениеШага, текстОшибки); + ВывестиСообщение(ПредставлениеШага, ВозможныеСтатусыВыполнения.Сломался); + КонецЕсли; + + КонецПопытки; + КонецЕсли; + КонецЕсли; + + Возврат Рез; +КонецФункции // ВыполнитьХукУзла_ПередВыполнением(Узел) + Функция ВыполнитьДействиеУзла(Знач НаборБиблиотечныхШагов, Знач Узел) СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; @@ -315,8 +391,9 @@ Функция ВыполнитьШаг(Знач АдресШага, Знач ПараметрыШага, Знач НаборБиблиотечныхШагов, Знач ПредставлениеШага) СтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; - ОписаниеИсполнителяШагов = НаборБиблиотечныхШагов[ЧитательГеркин.НормализоватьАдресШага(АдресШага)]; - Если ОписаниеИсполнителяШагов = Неопределено Тогда + ОписаниеИсполнителяШагов = Неопределено; + ШагРеализован = НаборБиблиотечныхШагов.Свойство(ЧитательГеркин.НормализоватьАдресШага(АдресШага), ОписаниеИсполнителяШагов); + Если Не ШагРеализован ИЛИ ОписаниеИсполнителяШагов = Неопределено Тогда СтатусВыполнения = ВозможныеСтатусыВыполнения.НеРеализован; Иначе Рефлектор = Новый Рефлектор; @@ -348,9 +425,10 @@ КонецЕсли; КонецПопытки; - ВывестиСообщение(ПредставлениеШага, СтатусВыполнения); КонецЕсли; + ВывестиСообщение(ПредставлениеШага, СтатусВыполнения); + Возврат СтатусВыполнения; КонецФункции // ВыполнитьШаг() @@ -371,19 +449,30 @@ Для каждого РезультатВыполненияФичи Из НаборРезультатовВыполнения Цикл Подстрока = РезультатВыполнения.Строки.Добавить(); ЧитательГеркин.СкопироватьДерево(Подстрока, РезультатВыполненияФичи.Строки[0]); - СтатусВыполнения = ЗапомнитьСамоеХудшееСостояние(СтатусВыполнения, Подстрока.СтатусВыполнения); КонецЦикла; + Возврат РезультатВыполнения; КонецФункции // СобратьЕдиноеДеревоИзНабораРезультатовВыполнения(НаборРезультатовВыполнения) +Функция ПолучитьИтоговыйСтатусВыполнения(Знач РезультатыВыполнения) Экспорт + ИтоговыйСтатусВыполнения = ВозможныеСтатусыВыполнения.НеВыполнялся; + Для каждого РезультатВыполненияФичи Из РезультатыВыполнения.Строки Цикл + ИтоговыйСтатусВыполнения = ЗапомнитьСамоеХудшееСостояние(РезультатВыполненияФичи.СтатусВыполнения, ИтоговыйСтатусВыполнения); + КонецЦикла; + + Возврат ИтоговыйСтатусВыполнения; +КонецФункции + Процедура РекурсивноПосчитатьИтогиВыполнения(Узел, СтруктураИтогов) - НужныйИтог = Неопределено; - ЕстьИтог = СтруктураИтогов.Свойство(Узел.ТипШага, НужныйИтог); - Если НЕ ЕстьИтог Тогда - Возврат; - КонецЕсли; + Если ТипЗнч(Узел) <> Тип("ДеревоЗначений") Тогда + НужныйИтог = Неопределено; + ЕстьИтог = СтруктураИтогов.Свойство(Узел.ТипШага, НужныйИтог); + Если НЕ ЕстьИтог Тогда + Возврат; + КонецЕсли; - НужныйИтог[Узел.СтатусВыполнения] = НужныйИтог[Узел.СтатусВыполнения] + 1; + НужныйИтог[Узел.СтатусВыполнения] = НужныйИтог[Узел.СтатусВыполнения] + 1; + КонецЕсли; Для Каждого СтрокаДерева Из Узел.Строки Цикл РекурсивноПосчитатьИтогиВыполнения(СтрокаДерева, СтруктураИтогов); @@ -428,22 +517,11 @@ КонецФункции -// реализация интерфейс раскладки для логов +// реализация интерфейса раскладки для логов Функция Форматировать(Знач Уровень, Знач Сообщение) Экспорт Отступ = ПолучитьОтступ(ТекущийУровень); - НаименованиеУровня = ""; - - Если Уровень = УровниЛога.Информация Тогда - НаименованиеУровня = ?(Лог.Уровень() <> Уровень, УровниЛога.НаименованиеУровня(Уровень) +Символы.Таб+ "- ", ""); - Сообщение = СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(Сообщение, Отступ); - Возврат СтрШаблон("%1%2", НаименованиеУровня, Сообщение); - КонецЕсли; - - НаименованиеУровня = УровниЛога.НаименованиеУровня(Уровень); - - Сообщение = СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(Сообщение, СтрШаблон("- %1", Отступ)); - Возврат СтрШаблон("%1 %2 %3", НаименованиеУровня, Символы.Таб, Сообщение); - + Сообщение = СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(Сообщение, Отступ); + Возврат Сообщение; КонецФункции // здесь нужно использовать различные виды форматирования @@ -475,7 +553,7 @@ Рез = Новый Соответствие; Рез.Вставить(ВозможныеСтатусыВыполнения.НеВыполнялся, Неопределено); Рез.Вставить(ВозможныеСтатусыВыполнения.Пройден, ЦветКонсоли.Зеленый); - Рез.Вставить(ВозможныеСтатусыВыполнения.НеРеализован, ЦветКонсоли.Серый); + Рез.Вставить(ВозможныеСтатусыВыполнения.НеРеализован, ЦветКонсоли.Бирюза); Рез.Вставить(ВозможныеСтатусыВыполнения.Сломался, ЦветКонсоли.Красный); Возврат Новый ФиксированноеСоответствие(Рез); @@ -508,10 +586,12 @@ ВозможныеЦветаСтатусовВыполнения = ВозможныеЦветаСтатусовВыполнения(); ТекущийУровень = 0; - ЧитательГеркин = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "gherkin-read.os")); + ЧитательГеркин = Новый ЧитательГеркин; ВозможныеТипыШагов = ЧитательГеркин.ВозможныеТипыШагов(); ВозможныеКлючиПараметров = ЧитательГеркин.ВозможныеКлючиПараметров(); + + Контекст = Новый Соответствие(); КонецФункции // } diff --git a/src/bdd-generate.os b/src/bdd-generate.os index 144d6e6..8efce5b 100644 --- a/src/bdd-generate.os +++ b/src/bdd-generate.os @@ -14,6 +14,8 @@ #Использовать logos #Использовать asserts +// #Использовать ".." + Перем Лог; Перем ЧитательГеркин; @@ -60,11 +62,11 @@ Функция СоздатьФайлРеализацииШагов(Знач ФайлФичи, Знач НаборБиблиотечныхШагов) Лог.Отладка("Подготовка к генерации шагов спецификации "+ФайлФичи.ПолноеИмя); - Ожидаем.Что(ФайлФичи, "Ожидали, что файл фичи будет передан как файл, а это не так").ИмеетТип("Файл"); + Ожидаем.Что(ФайлФичи, "Ожидали, что файл фичи будет передан как файл, а это не так").ИмеетТип("Файл"); РезультатыРазбора = ЧитательГеркин.ПрочитатьФайлСценария(ФайлФичи); ДеревоФич = РезультатыРазбора.ДеревоФич; - Ожидаем.Что(ДеревоФич, "Ожидали, что дерево фич будет передано как дерево значений, а это не так").ИмеетТип("ДеревоЗначений"); + Ожидаем.Что(ДеревоФич, "Ожидали, что дерево фич будет передано как дерево значений, а это не так").ИмеетТип("ДеревоЗначений"); ФайлШагов = ПолучитьФайлШагов(ФайлФичи); ИсключитьФайлШаговИзБиблиотечныхШагов(НаборБиблиотечныхШагов, ФайлШагов); @@ -91,7 +93,7 @@ Функция ПолучитьНаборБиблиотечныхШагов(Знач ФайлБиблиотек) //TODO подумать о замене на промежуточный класс, который собирает информацию о шагах в исполнителях - ИсполнительБДД = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "bdd-exec.os")); + ИсполнительБДД = Новый ИсполнительБДД; Набор = ИсполнительБДД.ПолучитьНаборБиблиотечныхШагов(ФайлБиблиотек); ОсвободитьОбъект(ИсполнительБДД); Возврат Набор; @@ -154,6 +156,10 @@ КонецЕсли; ЗаписатьОписанияШаговВФайлШагов(ОписаниеЗаписываемогоФайла, НаборШаговФичи); + ЗаписатьОписанияХуковВФайлШагов(ЧитательГеркин.ВозможныеХуки().ПередЗапускомСценария, "Процедура выполняется перед запуском каждого сценария", + ОписаниеЗаписываемогоФайла); + ЗаписатьОписанияХуковВФайлШагов(ЧитательГеркин.ВозможныеХуки().ПослеЗапускаСценария, "Процедура выполняется после завершения каждого сценария", + ОписаниеЗаписываемогоФайла); Если Не ЭтоПервичнаяГенерация Тогда ЗаписатьМетодыВФайл(ТаблицаМодуляШагов, НаборМетодовМодуляШагов, Буфер); @@ -291,15 +297,41 @@ Буфер.Добавить(""); Буфер.Добавить(Символы.Таб + "Возврат ВсеШаги;"); Буфер.Добавить("КонецФункции"); + Буфер.Добавить(""); Если ЭтоПервичнаяГенерация Тогда - Буфер.Добавить(""); Буфер.Добавить("// Реализация шагов"); Буфер.Добавить(""); КонецЕсли; КонецПроцедуры +Процедура ЗаписатьОписанияХуковВФайлШагов(Знач ОписаниеХука, Знач КомментарийДляХука, ОписаниеЗаписываемогоФайла) //, ЗНач НаборШаговФичи) + Буфер = ОписаниеЗаписываемогоФайла.Буфер; + ЭтоПервичнаяГенерация = ОписаниеЗаписываемогоФайла.ЭтоПервичнаяГенерация; + ТаблицаМодуляШагов = ОписаниеЗаписываемогоФайла.ТаблицаМодуляШагов; + НаборМетодовМодуляШагов = ОписаниеЗаписываемогоФайла.НаборМетодовМодуляШагов; + ФайлШагов = ОписаниеЗаписываемогоФайла.ФайлШагов; + + АдресХука = ОписаниеХука.АдресШага; + + Если Не ЭтоПервичнаяГенерация Тогда + ОписаниеМетода = НаборМетодовМодуляШагов.Найти(АдресХука, "НормализованноеИмяМетода"); + Если ОписаниеМетода <> Неопределено Тогда + ВывестиВБуферСтрокиТаблицы(Буфер, ТаблицаМодуляШагов, ОписаниеМетода.НомерСтрокиБлокаДоМетода, ОписаниеМетода.НомерСтрокиНачала-1); + Иначе + Возврат; + КонецЕсли; + КонецЕсли; + Буфер.Добавить(СтрШаблон("// %1", КомментарийДляХука)); + + Буфер.Добавить(СтрШаблон("Процедура %1(Знач Узел) Экспорт", АдресХука)); + Буфер.Добавить(Символы.Таб); + Буфер.Добавить("КонецПроцедуры"); + Буфер.Добавить(""); + +КонецПроцедуры + Процедура ВывестиВБуферСтрокиТаблицы(Буфер, ТаблицаМодуляШагов, Начало, Окончание) Для Счетчик = Начало По Окончание Цикл Строка = ТаблицаМодуляШагов[Счетчик].Строка; @@ -380,12 +412,15 @@ ЭтоПервичнаяГенерация = ОписаниеЗаписываемогоФайла.ЭтоПервичнаяГенерация; НаборМетодовМодуляШагов = ОписаниеЗаписываемогоФайла.НаборМетодовМодуляШагов; + АдресШага = ЧитательГеркин.НормализоватьАдресШага(ИмяМетода); + Если Не ЭтоПервичнаяГенерация Тогда - ОписаниеМетода = НаборМетодовМодуляШагов.Найти(ЧитательГеркин.НормализоватьАдресШага(ИмяМетода), "НормализованноеИмяМетода"); + ОписаниеМетода = НаборМетодовМодуляШагов.Найти(АдресШага, "НормализованноеИмяМетода"); Если ОписаниеМетода <> Неопределено Тогда Возврат; КонецЕсли; КонецЕсли; + Лог.Отладка("Адрес шага <"+АдресШага+">"); СтрокаПараметров = ПолучитьСтрокуПараметров(Узел.Параметры); @@ -398,7 +433,7 @@ КонецЦикла; ШаблонЗаписи = "%1 %2(%3) %4"; - СтрокаДляЗаписи = СтрШаблон(ШаблонЗаписи, "Процедура", ИмяМетода, СтрокаПараметров, "Экспорт"); + СтрокаДляЗаписи = СтрШаблон(ШаблонЗаписи, "Процедура", ИмяМетода, СтрокаПараметров, "Экспорт"); Лог.Отладка("СтрокаДляЗаписи <"+СтрокаДляЗаписи+">"); Буфер.Добавить(СтрокаДляЗаписи); @@ -421,11 +456,11 @@ Для Каждого ОписаниеПараметра Из Параметры Цикл Лог.Отладка("ОписаниеПараметра.Тип " + ОписаниеПараметра.Тип); ПредставлениеПараметра = ПолучитьПредставлениеПараметра(ОписаниеПараметра, Номер); - СтрокаПараметров = СтрокаПараметров + ПредставлениеПараметра + ","; + СтрокаПараметров = СтрШаблон("%1Знач %2,", СтрокаПараметров, ПредставлениеПараметра); Номер = Номер + 1; КонецЦикла; СтрокаПараметров = Лев(СтрокаПараметров, СтрДлина(СтрокаПараметров)-1); - КонецЕсли; + КонецЕсли; Возврат СтрокаПараметров; КонецФункции // ПолучитьСтрокуПараметров() @@ -442,7 +477,7 @@ Функция Инициализация() Лог = Логирование.ПолучитьЛог(ИмяЛога()); - ЧитательГеркин = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "gherkin-read.os")); + ЧитательГеркин = Новый ЧитательГеркин; ДопЛог = Логирование.ПолучитьЛог(ЧитательГеркин.ИмяЛога()); ДопЛог.УстановитьУровень(Лог.Уровень()); @@ -460,6 +495,7 @@ Рез.Вставить(ВозможныеКлючиПараметров.Число, "ПарамЧисло"); Рез.Вставить(ВозможныеКлючиПараметров.Дата, "ПарамДата"); Рез.Вставить(ВозможныеКлючиПараметров.ПараметрДляТаблицы, "Парам"); + Рез.Вставить(ВозможныеКлючиПараметров.Таблица, "ПарамТаблица"); Возврат Рез; КонецФункции // ВозможныеПредставленияТиповПараметров() diff --git a/src/bdd.os b/src/bdd.os index e5f54c3..a1863b8 100644 --- a/src/bdd.os +++ b/src/bdd.os @@ -12,12 +12,14 @@ #Использовать cmdline #Использовать logos +#Использовать ".." + Перем Лог; Перем УдалятьВременныеФайлы; Перем СохраненныйТекущийКаталог; Функция Версия() - Возврат "0.8"; + Возврат "0.9"; КонецФункции // Версия() //{ Точка входа в приложение @@ -155,7 +157,7 @@ ПутьИсполнителя = ОбъединитьПути(ТекущийСценарий().Каталог, "bdd-exec.os"); Лог.Отладка("Создаю исполнителя. Путь "+ПутьИсполнителя); - ИсполнительБДД = ЗагрузитьСценарий(ПутьИсполнителя); + ИсполнительБДД = Новый ИсполнительБДД; ДопЛог = Логирование.ПолучитьЛог(ИсполнительБДД.ИмяЛога()); ДопЛог.УстановитьУровень(Лог.Уровень()); @@ -167,9 +169,14 @@ ИскатьВПодкаталогах = Истина; РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(ФайлФичи, ФайлБиблиотек, ИскатьВПодкаталогах); - КодВозврата = ИсполнительБДД.ВозможныеКодыВозвратовПроцесса()[РезультатыВыполнения.Строки[0].СтатусВыполнения]; + Если РезультатыВыполнения.Строки.Количество() = 0 Тогда + КодВозврата = ИсполнительБДД.ВозможныеКодыВозвратовПроцесса()[ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся]; + Иначе + СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); + КодВозврата = ИсполнительБДД.ВозможныеКодыВозвратовПроцесса()[СтатусВыполнения]; - ИсполнительБДД.ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения); + ИсполнительБДД.ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения, ФайлФичи.ЭтоКаталог()); + КонецЕсли; Возврат КодВозврата; КонецФункции @@ -179,7 +186,7 @@ ПутьГенератора = ОбъединитьПути(ТекущийСценарий().Каталог, "bdd-generate.os"); Лог.Отладка("Создаю помощника для генерации файла шагов. Путь "+ПутьГенератора); - ГенераторШагов = ЗагрузитьСценарий(ПутьГенератора); + ГенераторШагов = Новый ГенераторШагов; ДопЛог = Логирование.ПолучитьЛог(ГенераторШагов.ИмяЛога()); ДопЛог.УстановитьУровень(Лог.Уровень()); diff --git a/src/gherkin-read.os b/src/gherkin-read.os index 963bf43..69fbd82 100644 --- a/src/gherkin-read.os +++ b/src/gherkin-read.os @@ -25,6 +25,7 @@ Перем ВозможныеТипыНачалаСтроки; Перем ВозможныеКлючевыеСлова; Перем ВозможныеКлючиПараметров; +Перем ВозможныеХуки; Перем УровниЛексем; Перем ТипыШагов; @@ -41,7 +42,8 @@ КонецЕсли; Лог.Отладка("Читаю сценарий "+ФайлСценария.ПолноеИмя); - Фича = Новый ЧтениеТекста(ФайлСценария.ПолноеИмя, "UTF-8"); + Фича = Новый ЧитательСтрокФайла; + Фича.Инициализировать(ФайлСценария.ПолноеИмя); СтруктураФичи = РазобратьТекстФичи(Фича); НайденныеЛексемы = СтруктураФичи.НайденныеЛексемы; @@ -86,9 +88,14 @@ Рез.Вставить("Число", "<ПараметрЧисло>"); Рез.Вставить("Дата", "<ПараметрДата>"); Рез.Вставить("ПараметрДляТаблицы", "<ПараметрДляТаблицы>"); + Рез.Вставить("Таблица", "<Таблица>"); Возврат Новый ФиксированнаяСтруктура(Рез); КонецФункции +Функция ВозможныеХуки() Экспорт + Возврат ВозможныеХуки; +КонецФункции // ВозможныеХуки() + Функция СоздатьДеревоФич() Экспорт Рез = Новый ДеревоЗначений; Рез.Колонки.Добавить("Лексема"); @@ -104,9 +111,6 @@ КонецФункции Функция НормализоватьАдресШага(Знач АдресШага) Экспорт - Для каждого КлючЗначение Из НаборЗаменДляНормализацииАдресаШага Цикл - АдресШага = СтрЗаменить(АдресШага, КлючЗначение.Ключ, КлючЗначение.Значение); - КонецЦикла; Возврат ВРег(АдресШага); КонецФункции // НормализоватьАдресШага() @@ -180,14 +184,11 @@ ПервыйСимвол = Лев(ОчереднаяСтрока, 1); Если ПервыйСимвол = ВозможныеТипыНачалаСтроки.Комментарий Тогда - //Лог.Отладка(" Первый символ строки - это комментарий."); НовыйЯзык = ПолучитьЯзыкФичи(ОчереднаяСтрока); Если ЗначениеЗаполнено(НовыйЯзык) Тогда Язык = НовыйЯзык; СоответствиеКлючевыеСлова = СоответствиеЯзыкКлючевыеСлова.Получить(Язык); Лог.Отладка(" Получили язык фичи "+Язык); - Иначе - //Лог.Отладка(" Пропускаю строку"); КонецЕсли; Продолжить; @@ -195,13 +196,25 @@ Лог.Отладка(" Первый символ строки - это метка. Пропускаю строку"); Продолжить; + ИначеЕсли ПервыйСимвол = ВозможныеТипыНачалаСтроки.Таблица И НЕ ПредыдущиеПараметрыЛексемы.ДалееБудутДополнительныеСтроки Тогда + Лог.Отладка("Очередная строка фичи <"+ОчереднаяСтрока+">"); + + ПредыдущиеПараметрыЛексемы.ЕстьТелоТаблицы = Истина; + ПредыдущиеПараметрыЛексемы.ДопТело = ПолучитьТелоТаблицыДанных(Фича, ОчереднаяСтрока); + + Лог.Отладка("Добавляю таблицу данных как часть предыдущей лексемы. Тело <%1>", ПредыдущиеПараметрыЛексемы.ДопТело); + Продолжить; + ИначеЕсли Лев(ОчереднаяСтрока, ДлинаСтрокиНачалаМногострочногоТекста) = ВозможныеТипыНачалаСтроки.МногострочныйТекст Тогда Лог.Отладка("Очередная строка фичи <"+ОчереднаяСтрока+">"); + ПредыдущиеПараметрыЛексемы.ЕстьМногострочнаяСтрока = Истина; + ПраваяЧасть = ПредыдущиеПараметрыЛексемы.ПраваяЧасть + ?(ПустаяСтрока(ПредыдущиеПараметрыЛексемы.ПраваяЧасть), "", Символы.ПС); ПредыдущиеПараметрыЛексемы.ПраваяЧасть = ПраваяЧасть + ПолучитьМногострочныйТекст(Фича); Лог.Отладка("Добавляю многострочный текст как часть предыдущей лексемы. Тело "+ПредыдущиеПараметрыЛексемы.ПраваяЧасть); Продолжить; + КонецЕсли; Лог.Отладка("Очередная строка фичи <"+ОчереднаяСтрока+">"); @@ -242,6 +255,9 @@ Рез.Вставить("Лексема", Неопределено); Рез.Вставить("ПраваяЧасть", ""); Рез.Вставить("ДалееБудутДополнительныеСтроки", Ложь); + Рез.Вставить("ДопТело", ""); + Рез.Вставить("ЕстьТелоТаблицы", Ложь); + Рез.Вставить("ЕстьМногострочнаяСтрока", Ложь); СтрокаДляПоиска = НРег(Строка); Для каждого КлючЗначение Из СоответствиеКлючевыеСлова Цикл @@ -283,7 +299,7 @@ Возврат Рез; КонецФункции -Функция ПолучитьОчереднуюСтрокуФичи(Знач Фича, Знач УдалятьПробелыСлева = Истина) +Функция ПолучитьОчереднуюСтрокуФичи(Знач Фича, Знач ПропускатьПустыеСтроки = Истина) Рез = ""; Пока Истина Цикл ОчереднаяСтрока = Фича.ПрочитатьСтроку(); @@ -292,12 +308,13 @@ Возврат Неопределено; КонецЕсли; - Если УдалятьПробелыСлева Тогда + Если ПропускатьПустыеСтроки Тогда Рез = СокрЛП(ОчереднаяСтрока); + Если Не ПустаяСтрока(Рез) Тогда + Прервать; + КонецЕсли; Иначе Рез = СокрП(ОчереднаяСтрока); - КонецЕсли; - Если Не ПустаяСтрока(Рез) Тогда Прервать; КонецЕсли; КонецЦикла; @@ -315,17 +332,17 @@ ЕстьФичи = ЗначениеЗаполнено(СтрокиДерева); Если ЕстьФичи Тогда -Лог.Отладка(СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(" -| ------------------- Текущее дерево (перед подменой структуры сценария): ------------------- -|", " ")); -ПоказатьДеревоВРежимеОтладки(ДеревоФич, " "); + Лог.Отладка(СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(" + | ------------------- Текущее дерево (перед подменой структуры сценария): ------------------- + |", " ")); + ПоказатьДеревоВРежимеОтладки(ДеревоФич, " "); СоздатьНовыеСценарииВУзлахДереваВместоСтруктурыСценария(СтрокиДерева); -Лог.Отладка(СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(" -| ------------------- Текущее дерево (перед подменой контекстов): ------------------- -|", " ")); -ПоказатьДеревоВРежимеОтладки(ДеревоФич, " "); + Лог.Отладка(СтроковыеФункции.ДополнитьСлеваМногострочнуюСтроку(" + | ------------------- Текущее дерево (перед подменой контекстов): ------------------- + |", " ")); + ПоказатьДеревоВРежимеОтладки(ДеревоФич, " "); ВставитьУзлыКонтекстовВУзлыСценариевПодчиненныхКонтексту(СтрокиДерева); КонецЕсли; @@ -338,52 +355,79 @@ Возврат ?(ЕстьФичи, ДеревоФич, Неопределено); КонецФункции +//TODO тяжелая функция, перегружена обязанностями. нужно отрефакторить Процедура ЗаполнитьДеревоФич(НайденныеЛексемы, СтрокиДерева, Индекс) + Пока Индекс < НайденныеЛексемы.Количество() Цикл ПараметрыОчереднойЛексемы = НайденныеЛексемы[Индекс]; ОчереднаяЛексема = ПараметрыОчереднойЛексемы.Лексема; УровеньЛексемы = УровниЛексем[ОчереднаяЛексема]; + Лог.Отладка("Получил Очередная лексема <"+ОчереднаяЛексема+">, Индекс "+Индекс+", уровень <"+УровеньЛексемы+">, тело <"+ПараметрыОчереднойЛексемы.ПраваяЧасть+">"); НайденныеПараметры = Неопределено; ПараметрыДляТаблицы = Неопределено; ЕстьПараметрыДляТаблицы = Ложь; - НоваяПраваяЧасть = ИзвлечьПараметры(ПараметрыОчереднойЛексемы.ПраваяЧасть, НайденныеПараметры, ПараметрыДляТаблицы, ЕстьПараметрыДляТаблицы); - Лог.Отладка("НоваяПраваяЧасть "+НоваяПраваяЧасть); + ПраваяЧастьСДобавленнымиКлючамиПараметров = ИзвлечьПараметры(ПараметрыОчереднойЛексемы, НайденныеПараметры, ПараметрыДляТаблицы, ЕстьПараметрыДляТаблицы); + Лог.Отладка("ПраваяЧастьСДобавленнымиКлючамиПараметров "+ПраваяЧастьСДобавленнымиКлючамиПараметров); - НоваяСтрока = ЗаполнитьУзелДереваФич(СтрокиДерева, ОчереднаяЛексема, ПараметрыОчереднойЛексемы.ПраваяЧасть); + ПолнаяПраваяЧасть = ПараметрыОчереднойЛексемы.ПраваяЧасть; + Если Не ПустаяСтрока(ПараметрыОчереднойЛексемы.ДопТело) Тогда + ПолнаяПраваяЧасть = ПолнаяПраваяЧасть + Символы.ПС + ПараметрыОчереднойЛексемы.ДопТело; + КонецЕсли; + НоваяСтрока = ЗаполнитьУзелДереваФич(СтрокиДерева, ОчереднаяЛексема, ПолнаяПраваяЧасть); Лог.Отладка("НоваяСтрока.Лексема <"+НоваяСтрока.Лексема+">"); НоваяСтрока.Параметры = НайденныеПараметры; НоваяСтрока.ПараметрыДляТаблицы = ПараметрыДляТаблицы; НоваяСтрока.ЕстьПараметрыДляТаблицы = ЕстьПараметрыДляТаблицы; НоваяСтрока.ТипШага = ПолучитьТипШагаПоЛексеме(ОчереднаяЛексема); - НоваяСтрока.АдресШага = СформироватьАдресШага(НоваяПраваяЧасть); + НоваяСтрока.АдресШага = СформироватьАдресШага(ПраваяЧастьСДобавленнымиКлючамиПараметров); НоваяСтрока.УровеньЛексемы = УровеньЛексемы; - СтараяСтрока = НоваяСтрока; - Индекс = Индекс + 1; Если Индекс >= НайденныеЛексемы.Количество() Тогда Лог.Отладка("Завершаю изучать лексемы. Индекс "+Индекс); Прервать; КонецЕсли; - ОставатьсяНаЭтомЖеУровнеДерева = ОчереднаяЛексема = ВозможныеКлючевыеСлова.Описание; - Если ОставатьсяНаЭтомЖеУровнеДерева Тогда - Продолжить; - КонецЕсли; НоваяЛексема = НайденныеЛексемы[Индекс].Лексема; НовыйУровеньЛексемы = УровниЛексем[НоваяЛексема]; - Лог.Отладка(СтрШаблон("Проверяю следующую лексему <%1>, Индекс %2, уровень <%3>, верхний уровень %4", НоваяЛексема, Индекс, НовыйУровеньЛексемы, УровеньЛексемы)); + Лог.Отладка(СтрШаблон("Проверяю следующую лексему <%1>, Индекс %2, уровень <%3>, верхний уровень %4", + НоваяЛексема, Индекс, НовыйУровеньЛексемы, УровеньЛексемы)); + Если НовыйУровеньЛексемы = УровеньЛексемы Тогда Продолжить; ИначеЕсли НовыйУровеньЛексемы > УровеньЛексемы Тогда // TODO здесь должны быть равнозначные узлы. Например, сценарий/примеры - Лог.Отладка("Создаю подчиненный узел дерева фич, лексема <"+НоваяЛексема+">, Индекс "+Индекс+", уровень <"+НовыйУровеньЛексемы+">"); + Лог.Отладка(СтрШаблон("Создаю подчиненный узел дерева фич, лексема %1, Индекс %2, уровень %3", + НоваяЛексема, Индекс, НовыйУровеньЛексемы)); ЗаполнитьДеревоФич(НайденныеЛексемы, НоваяСтрока.Строки, Индекс); Иначе - Лог.Отладка("Возвращаюсь на предыдущий уровень дерева фич"); - Возврат; + Родитель = НоваяСтрока.Родитель; + УровеньЛексемыРодителя = Родитель.УровеньЛексемы; + Лог.Отладка(СтрШаблон("Уровень следующей лексемы меньше уровня текущей лексемы + |Проверяю уровень родителя <%1>, Индекс %2, уровень <%3>", + Родитель.Лексема, Индекс, УровеньЛексемыРодителя)); + Если НовыйУровеньЛексемы < УровеньЛексемыРодителя Тогда + Лог.Отладка("Возвращаюсь на предыдущий уровень дерева фич"); + ЗаполнитьДеревоФич(НайденныеЛексемы, Родитель.Строки, Индекс); + Возврат; + Иначе + Пока Истина Цикл + Если НовыйУровеньЛексемы <= УровеньЛексемыРодителя Тогда + Лог.Отладка("Возвращаюсь на предыдущий уровень дерева фич"); + ЗаполнитьДеревоФич(НайденныеЛексемы, Родитель.Родитель.Строки, Индекс); + Возврат; + Иначе + Родитель = Родитель.Родитель; + Если Родитель = Неопределено Тогда + Прервать; + Иначе + КонецЕсли; + УровеньЛексемыРодителя = Родитель.УровеньЛексемы; + КонецЕсли; + КонецЦикла; + КонецЕсли; КонецЕсли; КонецЦикла; @@ -397,13 +441,21 @@ Возврат НоваяСтрока; КонецФункции -Функция ИзвлечьПараметры(Знач Тело, НайденныеПараметры, ПараметрыДляТаблицы, ЕстьПараметрыДляТаблицы) +Функция ИзвлечьПараметры(Знач ПараметрыЛексемы, НайденныеПараметры, ПараметрыДляТаблицы, ЕстьПараметрыДляТаблицы) + Тело = ПараметрыЛексемы.ПраваяЧасть; + НайденныеПараметры = СоздатьТаблицуПараметров(); ПараметрыДляТаблицы = СоздатьТаблицуПараметров(); - Тело = ВыделитьПараметрыИзТаблицы(Тело, НайденныеПараметры, ЕстьПараметрыДляТаблицы); + Тело = ВыделитьПараметрыДляПодстановкиТаблицы(Тело, НайденныеПараметры, ЕстьПараметрыДляТаблицы); - Тело = ВыделитьПараметрыИзМногострочногоТекста(Тело, НайденныеПараметры); + Если ПараметрыЛексемы.ЕстьТелоТаблицы Тогда + Тело = СтрШаблон("%1 %2", Тело, ИзвлечьПараметрТаблица(ПараметрыЛексемы.ДопТело, НайденныеПараметры)); + Лог.Отладка("Тело после извлечения параметра-таблицы %1", Тело); + КонецЕсли; + Если ПараметрыЛексемы.ЕстьМногострочнаяСтрока Тогда + Тело = ВыделитьПараметрыИзМногострочногоТекста(Тело, НайденныеПараметры); + КонецЕсли; Тело = ВыделитьСтроковыеПараметры(Тело, НайденныеПараметры, "'"); Тело = ВыделитьСтроковыеПараметры(Тело, НайденныеПараметры, """"); @@ -547,7 +599,7 @@ КонецФункции -Функция ВыделитьПараметрыИзТаблицы(Знач Тело, Параметры, ЕстьПараметрыДляТаблицы) +Функция ВыделитьПараметрыДляПодстановкиТаблицы(Знач Тело, Параметры, ЕстьПараметрыДляТаблицы) РегулярноеВыражение = РегулярныеВыражения.ПараметрДляТаблицы; КоллекцияГруппСовпадений = РегулярноеВыражение.НайтиСовпадения(Тело); ЕстьПараметрыДляТаблицы = КоллекцияГруппСовпадений.Количество() <> 0; @@ -571,7 +623,20 @@ КонецЦикла; Возврат НовоеТело; -КонецФункции // ВыделитьПараметрыИзТаблицы(НовоеТело, Параметры) +КонецФункции // ВыделитьПараметрыДляПодстановкиТаблицы(НовоеТело, Параметры) + +Функция ИзвлечьПараметрТаблица(Знач ТекстТаблицы, Параметры) + Если Лев(ТекстТаблицы, 1) <> ВозможныеТипыНачалаСтроки.Таблица Тогда + Возврат ТекстТаблицы; + КонецЕсли; + Таблица = ПолучитьТаблицу(ТекстТаблицы); + ОписаниеПараметра = ВозможныеКлючиПараметров.Таблица; + Начало = 100000;// чтобы параметр-таблица всегда шел последним в списке параметров + + ДобавитьПараметр(Параметры, ОписаниеПараметра, Таблица, Начало); + + Возврат ОписаниеПараметра; +КонецФункции // ИзвлечьПараметрТаблица(Тело, Параметры) Функция СоздатьТаблицуПараметров() Рез = Новый ТаблицаЗначений; @@ -615,10 +680,13 @@ Лог.Отладка("Пропускаю Элемент "+Элемент); Продолжить; КонецЕсли; - Элемент = СтрЗаменить(Элемент, "-", "_"); АдресШага = АдресШага + ТРег(Элемент); КонецЦикла; + Для каждого КлючЗначение Из НаборЗаменДляНормализацииАдресаШага Цикл + АдресШага = СтрЗаменить(АдресШага, КлючЗначение.Ключ, КлючЗначение.Значение); + КонецЦикла; + Возврат АдресШага; КонецФункции @@ -654,7 +722,9 @@ СтрокаДерева = Элемент.СтрокаДерева; УзелПримеры = НайтиШагПримеры(СтрокаДерева); - ТаблицаПримеров = ПолучитьТаблицуПримеров(УзелПримеры.Тело); + ТаблицаПримеров = ПолучитьТаблицу(УзелПримеры.Тело); + ИспользоватьПервуюСтрокуКакИменаКолонокТаблицы(ТаблицаПримеров); + СтрокаДерева.Строки.Удалить(УзелПримеры); СтрокиДерева.Удалить(СтрокаДерева); @@ -675,53 +745,78 @@ ВызватьИсключение СтрШаблон("Ошибка формата файла-фичи - Для структуры сценария не удалось найти примеры. Название структуры сценария %1", ИсходныйУзел.Тело); КонецФункции // НайтиШагПримеры(Строка) -Функция ПолучитьТаблицуПримеров(Знач ТекстПримеров) +Функция ПолучитьТаблицу(Знач ТекстТаблицы) - ЧислоСтрок = СтрЧислоСтрок(ТекстПримеров); - Ожидаем.Что(ЧислоСтрок, СтрШаблон("Неверное количество строк из таблицы примеров. Текст %1", ТекстПримеров)).Больше(1); + ЧислоСтрок = СтрЧислоСтрок(ТекстТаблицы); + Ожидаем.Что(ЧислоСтрок, СтрШаблон("Количество строк из таблицы должно быть больше 0, а это не так. Текст %1", ТекстТаблицы)).Больше(0); РезТаблица = Новый ТаблицаЗначений; - СтрокаИменКолонокИзПримеров = СтрПолучитьСтроку(ТекстПримеров, 1); - Лог.Отладка(СтрШаблон("Первая СтрокаПримеров %1", СтрокаИменКолонокИзПримеров)); - - МассивИменКолонок = ПолучитьНаборПримеровИзСтрокиПримеров(СтрокаИменКолонокИзПримеров); - Для НомерКолонки = 0 По МассивИменКолонок.Количество() - 1 Цикл - ИмяКолонки = МассивИменКолонок[НомерКолонки]; - Лог.Отладка(СтрШаблон("имя колонки %1 (для подстановки из таблицы) <%2>", НомерКолонки, ИмяКолонки)); - РезТаблица.Колонки.Добавить("К"+НомерКолонки,, ИмяКолонки); + МассивЗначенийПервойСтроки = ПолучитьНаборЗначенийИзТекстовойСтрокиТаблицы(ТекстТаблицы, 1); + Для НомерКолонки = 0 По МассивЗначенийПервойСтроки.Количество() - 1 Цикл + РезТаблица.Колонки.Добавить("К"+НомерКолонки); КонецЦикла; + НоваяСтрока = РезТаблица.Добавить(); + ЗаполнитьСтрокуТаблицы(МассивЗначенийПервойСтроки, НоваяСтрока, 0); + Для НомерСтроки = 2 По ЧислоСтрок Цикл - СтрокаПримеров = СтрПолучитьСтроку(ТекстПримеров, НомерСтроки); - Лог.Отладка(СтрШаблон(" СтрокаПримеров №%2 %1", СтрокаПримеров, НомерСтроки-1)); - МассивЗначений = ПолучитьНаборПримеровИзСтрокиПримеров(СтрокаПримеров); + МассивЗначений = ПолучитьНаборЗначенийИзТекстовойСтрокиТаблицы(ТекстТаблицы, НомерСтроки); Если МассивЗначений = Неопределено Тогда Прервать; КонецЕсли; - Ожидаем.Что(МассивЗначений, СтрШаблон("Неверное количество строк из таблицы примеров. Текст %1", ТекстПримеров)).ИмеетДлину(МассивИменКолонок.Количество()); + Ожидаем.Что(МассивЗначений, СтрШаблон("Получили неверное количество строк из таблицы. Текст %1", ТекстТаблицы)).ИмеетДлину(МассивЗначенийПервойСтроки.Количество()); НоваяСтрока = РезТаблица.Добавить(); - Для к = 0 По МассивЗначений.Количество() - 1 Цикл - ЗначениеПараметра = МассивЗначений[к]; - - //пытаемся привести к одному значению, все значения, кроме строки. Например, число, дата - НайденныеПараметры = СоздатьТаблицуПараметров(); - ВыделитьПростыеЗначенияНеСтроки(ЗначениеПараметра, НайденныеПараметры); - Если НайденныеПараметры.Количество() = 1 Тогда - ЗначениеПараметра = НайденныеПараметры[0].Значение; - КонецЕсли; - - Лог.Отладка(СтрШаблон("номер строки %3, значение из колонки %1 (для подстановки из таблицы) <%2>", к, ЗначениеПараметра, НомерСтроки-1)); - НоваяСтрока[к] = ЗначениеПараметра; - КонецЦикла; + ЗаполнитьСтрокуТаблицы(МассивЗначений, НоваяСтрока, НомерСтроки); КонецЦикла; Возврат РезТаблица; -КонецФункции // ПолучитьТаблицуПримеров(УзелПримеры) +КонецФункции // ПолучитьТаблицу(Тело) + +Функция ПолучитьНаборЗначенийИзТекстовойСтрокиТаблицы(Знач ТекстТаблицы, Знач НомерСтроки) + СтрокаТекстовойТаблицы = СтрПолучитьСтроку(ТекстТаблицы, НомерСтроки); + Если НомерСтроки = 1 Тогда + Лог.Отладка(СтрШаблон("Первая СтрокаПримеров %1", СтрокаТекстовойТаблицы)); + Иначе + Лог.Отладка(СтрШаблон(" СтрокаПримеров №%2 %1", СтрокаТекстовойТаблицы, НомерСтроки-1)); + КонецЕсли; + МассивЗначений = ПолучитьНаборИзСтрокиТаблицы(СтрокаТекстовойТаблицы); + Возврат МассивЗначений; +КонецФункции // ПолучитьНаборЗначенийИзТекстовойСтрокиТаблицы() + +Процедура ЗаполнитьСтрокуТаблицы(Знач МассивЗначений, НоваяСтрока, Знач НомерСтроки) + Для к = 0 По МассивЗначений.Количество() - 1 Цикл + ЗначениеПараметра = МассивЗначений[к]; + + //пытаемся привести к одному значению, все значения, кроме строки. Например, число, дата + НайденныеПараметры = СоздатьТаблицуПараметров(); + ВыделитьПростыеЗначенияНеСтроки(ЗначениеПараметра, НайденныеПараметры); + Если НайденныеПараметры.Количество() = 1 Тогда + ЗначениеПараметра = НайденныеПараметры[0].Значение; + КонецЕсли; -Функция ПолучитьНаборПримеровИзСтрокиПримеров(Знач СтрокаПримеров) + Лог.Отладка(СтрШаблон("номер строки %3, значение из колонки %1 (для подстановки из таблицы) <%2>", к, ЗначениеПараметра, НомерСтроки-1)); + НоваяСтрока[к] = ЗначениеПараметра; + КонецЦикла; +КонецПроцедуры + +Процедура ИспользоватьПервуюСтрокуКакИменаКолонокТаблицы(Таблица) + Ожидаем.Что(Таблица.Количество(), "Количество строк из таблицы примеров должно быть больше 1, а это не так").Больше(1); + + ПерваяСтрока = Таблица[0]; + + Для НомерКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл + ИмяКолонки = ПерваяСтрока[НомерКолонки]; + Лог.Отладка(СтрШаблон("имя колонки %1 (для подстановки из таблицы) <%2>", НомерКолонки, ИмяКолонки)); + Колонка = Таблица.Колонки[НомерКолонки]; + Колонка.Заголовок = ИмяКолонки; + КонецЦикла; + Таблица.Удалить(0); +КонецПроцедуры // ИспользоватьПервуюСтрокуКакИменаКолонокТаблицы(Таблица) + +Функция ПолучитьНаборИзСтрокиТаблицы(Знач СтрокаТаблицы) РегулярноеВыражение = РегулярныеВыражения.ПараметрТаблицы; - КоллекцияГруппСовпадений = РегулярноеВыражение.НайтиСовпадения(СтрокаПримеров); + КоллекцияГруппСовпадений = РегулярноеВыражение.НайтиСовпадения(СтрокаТаблицы); Если КоллекцияГруппСовпадений.Количество() = 0 Тогда Возврат Неопределено; КонецЕсли; @@ -733,7 +828,7 @@ РезМассив.Добавить(ЗначениеПараметра); КонецЦикла; Возврат РезМассив; -КонецФункции // ПолучитьНаборПримеровИзСтрокиПримеров() +КонецФункции // ПолучитьНаборИзСтрокиТаблицы() Функция СоздатьНовыеСтрокиСценариевСПараметрамиИзПримеров(СтрокиДерева, Знач СчетчикСтрокиВДереве, Знач СтрокаДерева, Знач ТаблицаПримеров) МассивНовыхСтрок = Новый Массив; @@ -763,7 +858,7 @@ ЗначенияПараметров.Вставить(ИмяПараметра, СтрокаТаблицыПримеров[ИмяКолонки]); Лог.Отладка(СтрШаблон("представление колонки <%3>, значение колонки <%2>, ИмяКолонки из таблицы <%1>, тело узла - %4 ", - ИмяКолонки, СтрокаТаблицыПримеров[ИмяКолонки], ИмяПараметра, СтрокаДерева.Тело)); + ИмяКолонки, СтрокаТаблицыПримеров[ИмяКолонки], ИмяПараметра, СтрокаДерева.Тело)); КонецЦикла; Для каждого Параметр Из СтрокаДерева.Параметры Цикл Если Параметр.Тип <> ВозможныеКлючиПараметров.ПараметрДляТаблицы Тогда @@ -775,7 +870,7 @@ СтрокаДерева.Тело = СтрЗаменить(СтрокаДерева.Тело, "<"+ИмяПараметра+">", "<"+Параметр.Значение+">"); Лог.Отладка(СтрШаблон("ИмяПараметра из таблицы <%1>, новое значение <%2>, ЗначенияПараметров[ИмяПараметра] <%3>, тело узла - %4, тип %5 ", - ИмяПараметра, Параметр.Значение, ЗначенияПараметров[ИмяПараметра], СтрокаДерева.Тело, Параметр.Тип)); + ИмяПараметра, Параметр.Значение, ЗначенияПараметров[ИмяПараметра], СтрокаДерева.Тело, Параметр.Тип)); КонецЦикла; КонецЕсли; Для каждого ПодчиненнаяСтрока Из СтрокаДерева.Строки Цикл @@ -786,29 +881,20 @@ Процедура ВставитьУзлыКонтекстовВУзлыСценариевПодчиненныхКонтексту(СтрокиДерева, Знач СчетчикСтрокиВДереве = 0, Знач УзелКонтекста = Неопределено) Для Счетчик = СчетчикСтрокиВДереве По СтрокиДерева.Количество() -1 Цикл -Лог.Ошибка("Счетчик в цикле %1, кол-во строк %2", Счетчик, СтрокиДерева.Количество() -1); СтрокаДерева = СтрокиДерева[Счетчик]; - Лог.Ошибка(" Лексема <%1>, Тело <%2>, уровень <%3>, уровень() %4", СтрокаДерева.Лексема, СтрокаДерева.Тело, СтрокаДерева.УровеньЛексемы, СтрокаДерева.Уровень()); - //Если ТипЗнч(СтрокаДерева.Владелец()) <> Тип("ДеревоЗначений") Тогда - // Лог.Ошибка(" Лексема <%1>, Тело <%2>, уровень <%3>", СтрокаДерева.Владелец().Лексема, СтрокаДерева.Владелец().Тело, СтрокаДерева.Владелец().УровеньЛексемы); - //КонецЕсли; + Лог.Отладка(" Лексема <%1>, Тело <%2>, уровень <%3>, уровень() %4", СтрокаДерева.Лексема, СтрокаДерева.Тело, СтрокаДерева.УровеньЛексемы, СтрокаДерева.Уровень()); Если СтрокаДерева.Уровень() > 1 Тогда - Лог.Ошибка(" Пропускаю строку "); Прервать; КонецЕсли; Если СтрокаДерева.ТипШага = ВозможныеТипыШагов.Контекст Тогда Лог.Отладка(СтрШаблон("Найден контекст <%1>", СтрокаДерева.Тело)); - //Если УзелКонтекста = Неопределено Тогда - СтрокиДерева.Удалить(СтрокаДерева); - ВставитьУзлыКонтекстовВУзлыСценариевПодчиненныхКонтексту(СтрокиДерева, Счетчик, СтрокаДерева); - Прервать; - //Иначе - //КонецЕсли; + СтрокиДерева.Удалить(СтрокаДерева); + ВставитьУзлыКонтекстовВУзлыСценариевПодчиненныхКонтексту(СтрокиДерева, Счетчик, СтрокаДерева); + Прервать; Иначе Если УзелКонтекста <> Неопределено Тогда Если СтрокаДерева.УровеньЛексемы = УзелКонтекста.УровеньЛексемы Тогда - //МассивСтрокДляВставкиКонтекста.Добавить(СтрокаДерева); МассивСтрокДляВставкиКонтекста = Новый Массив; МассивСтрокДляВставкиКонтекста.Добавить(СтрокаДерева); ВставитьУзелКонтекста(МассивСтрокДляВставкиКонтекста, УзелКонтекста); @@ -823,65 +909,10 @@ КонецЦикла; КонецПроцедуры -// -//Процедура ВставитьУзлыКонтекстовВУзлыСценариевПодчиненныхКонтексту(СтрокиДерева) -// КоличествоСтрок = СтрокиДерева.Количество() - 1; -// Для Счетчик = 0 По КоличествоСтрок Цикл -// //Пока Счетчик <= КоличествоСтрок Цикл -// // Счетчик = Счетчик + 1; -// -//Лог.Ошибка("Счетчик в цикле %1, кол-во строк %2", Счетчик, КоличествоСтрок); -// Если Счетчик > КоличествоСтрок Тогда -// Прервать; -// КонецЕсли; -// СтрокаДерева = СтрокиДерева[Счетчик]; -// Лог.Ошибка(" Лексема <%1>, Тело <%2>", СтрокаДерева.Лексема, СтрокаДерева.Тело); -// Если СтрокаДерева.ТипШага = ВозможныеТипыШагов.Контекст Тогда -// Лог.Отладка(СтрШаблон("Найден контекст <%1>", СтрокаДерева.Тело)); -// СтрокиДерева.Удалить(СтрокаДерева); -// КоличествоСтрок = КоличествоСтрок - 1; -// -// МассивСтрокДляВставкиКонтекста = Новый Массив; -// Для СчетчикСценариев = Счетчик По КоличествоСтрок Цикл -// //Для СчетчикСценариев = Счетчик + 1 По КоличествоСтрок Цикл -// СтрокаСценария = СтрокиДерева[СчетчикСценариев]; -// -// // каждый новый контекст вытесняет предыдущий контекст -// Если СтрокаСценария.ТипШага = ВозможныеТипыШагов.Контекст Тогда -// ВставитьУзелКонтекста(МассивСтрокДляВставкиКонтекста, СтрокаДерева); -// МассивСтрокДляВставкиКонтекста = Новый Массив; -// -// Счетчик = СчетчикСценариев; -// //Счетчик = СчетчикСценариев - 1; -// -// //СтрокиДерева.Удалить(СтрокаДерева); -// //Счетчик = Счетчик - 1; -// Прервать; -// КонецЕсли; -// -// Если СтрокаСценария.УровеньЛексемы = СтрокаДерева.УровеньЛексемы Тогда -// МассивСтрокДляВставкиКонтекста.Добавить(СтрокаСценария); -// КонецЕсли; -// КонецЦикла; -// ВставитьУзелКонтекста(МассивСтрокДляВставкиКонтекста, СтрокаДерева); -// СтрокиДерева.Удалить(СтрокаДерева); -// Лог.Ошибка("Счетчик до удаления %1, кол-во строк %2", Счетчик, КоличествоСтрок); -// Лог.Ошибка(" до удаления Лексема <%1>, Тело <%2>", СтрокаДерева.Лексема, СтрокаДерева.Тело); -// Счетчик = Счетчик - 1; -// КоличествоСтрок = КоличествоСтрок - 1; -// Лог.Ошибка("Счетчик при удалении %1, кол-во строк %2", Счетчик, КоличествоСтрок); -// СтрокаДереваВрем = СтрокиДерева[Счетчик]; -// Лог.Ошибка(" после удаления Лексема <%1>, Тело <%2>", СтрокаДереваВрем.Лексема, СтрокаДереваВрем.Тело); -// ПоказатьДеревоВРежимеОтладки(СтрокаДереваВрем.Владелец(), " "); -// Иначе -// ВставитьУзлыКонтекстовВУзлыСценариевПодчиненныхКонтексту(СтрокаДерева.Строки); -// КонецЕсли; -// КонецЦикла; -//КонецПроцедуры - Процедура ВставитьУзелКонтекста(Знач МассивСтрокДляВставкиКонтекста, Знач УзелКонтекста) Для каждого СтрокаСценария Из МассивСтрокДляВставкиКонтекста Цикл -Лог.Ошибка(СтрШаблон("Вставляю контекст для строки <%1>, контекст <%2>", СтрокаСценария.Тело, УзелКонтекста.Тело)); + Лог.Отладка(СтрШаблон("Вставляю контекст для строки <%1>, контекст <%2>", СтрокаСценария.Тело, УзелКонтекста.Тело)); + НоваяСтрока = СтрокаСценария.Строки.Вставить(0); СкопироватьДерево(НоваяСтрока, УзелКонтекста); ПоказатьДеревоВРежимеОтладки(СтрокаСценария, " "); @@ -936,7 +967,11 @@ Если ОчереднаяСтрока = Неопределено или Лев(СокрЛ(ОчереднаяСтрока), ДлинаСтрокиНачалаМногострочногоТекста) = ВозможныеТипыНачалаСтроки.МногострочныйТекст Тогда Прервать; КонецЕсли; - МногострочнаяСтрока = МногострочнаяСтрока + Сред(ОчереднаяСтрока, Отступ) + Символы.ПС; + // проверю, нет ли в отсекаемоей левой части строки непробельных символов, которые нужно сохранить + ПозицияПервогоНеПробельногоСимвола = НайтиПозициюПервогоНеПробельногоСимвола(Лев(ОчереднаяСтрока, Отступ-1)); + + ДобавляемаяСтрока = Сред(ОчереднаяСтрока, Мин(Отступ, ПозицияПервогоНеПробельногоСимвола)); + МногострочнаяСтрока = МногострочнаяСтрока + ДобавляемаяСтрока + Символы.ПС; КонецЦикла; Если Прав(МногострочнаяСтрока, 1) = Символы.ПС Тогда МногострочнаяСтрока = Сред(МногострочнаяСтрока, 1, СтрДлина(МногострочнаяСтрока) - 1); @@ -945,11 +980,41 @@ Возврат МногострочнаяСтрока; КонецФункции // ПолучитьМногострочныйТекст() +Функция НайтиПозициюПервогоНеПробельногоСимвола(Знач Строка) + КоллекцияГруппСовпадений = РегулярныеВыражения.ПробельныеСимволы.НайтиСовпадения(Строка); + Если КоллекцияГруппСовпадений.Количество() = 0 Тогда + Возврат СтрДлина(Строка)+1; + КонецЕсли; + Совпадение = КоллекцияГруппСовпадений[0]; + Значение = Совпадение.Группы[0].Значение; + Поз = Совпадение.Группы[0].Индекс; + Возврат Поз; + +КонецФункции // НайтиПозициюПервогоНепробельногоСимвола() + +Функция ПолучитьТелоТаблицыДанных(Фича, ОчереднаяСтрока) + Рез = ОчереднаяСтрока; + Пока Истина Цикл + ОчереднаяСтрока = ПолучитьОчереднуюСтрокуФичи(Фича, Ложь); + Если ОчереднаяСтрока = Неопределено Тогда + Прервать; + КонецЕсли; + ОчереднаяСтрока = СокрЛП(ОчереднаяСтрока); + + Если Лев(ОчереднаяСтрока, 1) <> ВозможныеТипыНачалаСтроки.Таблица Тогда + Фича.ВернутьсяНаСтрокуНазад(); + Прервать; + КонецЕсли; + Рез = Рез + Символы.ПС + ОчереднаяСтрока; + КонецЦикла; + Возврат Рез; +КонецФункции // ПолучитьТелоТаблицыДанных(Фича) + Функция ВозможныеТипыНачалаСтроки() Рез = Новый Структура; Рез.Вставить("Комментарий", "#"); Рез.Вставить("Метка", "@"); - Рез.Вставить("Пример", "|"); + Рез.Вставить("Таблица", "|"); Рез.Вставить("ОбычныйТекст", 1); Рез.Вставить("МногострочныйТекст", """"""""); Возврат Новый ФиксированнаяСтруктура(Рез); @@ -965,6 +1030,7 @@ ВозможныеТипыШагов = ВозможныеТипыШагов(); ВозможныеТипыНачалаСтроки = ВозможныеТипыНачалаСтроки(); ВозможныеКлючиПараметров = ВозможныеКлючиПараметров(); + ВозможныеХуки = СоздатьВозможныеХуки(); ОписанияЛексем = ОписанияЛексем(); @@ -1073,19 +1139,53 @@ Рез.Вставить("МногострочныйТекст", Новый РегулярноеВыражение("\s*""""""\n\r*((.*\n\r*)+)\s*""""""")); Рез.Вставить("ПараметрДляТаблицы", Новый РегулярноеВыражение("<([^>]+)>")); Рез.Вставить("ПараметрТаблицы", Новый РегулярноеВыражение("\|\s*([^\|]+)\s*")); + Рез.Вставить("ПробельныеСимволы", Новый РегулярноеВыражение("[^\s]")); Возврат Новый ФиксированнаяСтруктура(Рез); КонецФункции // СоздатьРегулярныеВыражения() Функция СоздатьНаборЗаменДляНормализацииАдресаШага() Соответствие = Новый Соответствие; Соответствие.Вставить(" ","_"); - Соответствие.Вставить(",",""); - Соответствие.Вставить("(",""); - Соответствие.Вставить(")",""); - Соответствие.Вставить(";",""); - Соответствие.Вставить(".",""); + Соответствие.Вставить(",","_"); + Соответствие.Вставить("(","_"); + Соответствие.Вставить(")","_"); + Соответствие.Вставить(";","_"); + Соответствие.Вставить(".","_"); + + Соответствие.Вставить("`","_"); + Соответствие.Вставить("~","_"); + Соответствие.Вставить("!","_"); + Соответствие.Вставить("@","_"); + Соответствие.Вставить("#","_"); + Соответствие.Вставить("$","_"); + Соответствие.Вставить("%","_"); + Соответствие.Вставить("^","_"); + Соответствие.Вставить("&","_"); + Соответствие.Вставить("*","_"); + Соответствие.Вставить("'","_"); + Соответствие.Вставить("/","_"); + Соответствие.Вставить("\","_"); + Соответствие.Вставить(":","_"); + Соответствие.Вставить("-","_"); + Соответствие.Вставить("+","_"); + Соответствие.Вставить("=","_"); + Соответствие.Вставить("№","_"); + Соответствие.Вставить("?","_"); + Соответствие.Вставить("<","_"); + Соответствие.Вставить(">","_"); + Возврат Соответствие; КонецФункции // СоздатьНаборЗаменДляНормализацииАдресаШага() + +// возвращает Структуру, в которой ключ - имя хука, а значение - Структура с ключами АдресШага и ТипШага +Функция СоздатьВозможныеХуки() + Рез = Новый Структура; + //TODO добавить возможность единого набора хуков "до выполнения" и "после выполнения" шагов различных типов + //Например, перед запуском - для сценариев, шагов + Рез.Вставить("ПередЗапускомСценария", Новый Структура("АдресШага,ТипШага", "ПередЗапускомСценария", ВозможныеТипыШагов.Сценарий)); + Рез.Вставить("ПослеЗапускаСценария", Новый Структура("АдресШага,ТипШага", "ПослеЗапускаСценария", ВозможныеТипыШагов.Сценарий)); + Возврат Новый ФиксированнаяСтруктура(Рез); +КонецФункции // СоздатьВозможныеХуки() // } /////////////////////////////////////////////////////////////////// diff --git a/tests/exec-feature-tests.os b/tests/exec-feature-tests.os index b769f9d..63c52dd 100644 --- a/tests/exec-feature-tests.os +++ b/tests/exec-feature-tests.os @@ -15,6 +15,8 @@ #Использовать asserts #Использовать tempfiles +#Использовать ".." + Перем юТест; Перем Лог; Перем ЧитательГеркин; @@ -170,9 +172,8 @@ Функция Инициализация() Лог = Логирование.ПолучитьЛог("bdd-tests"); - ИсполнительБДД = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "../src/bdd-exec.os")); - - ЧитательГеркин = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "../src/gherkin-read.os")); + ИсполнительБДД = Новый ИсполнительБДД; + ЧитательГеркин = Новый ЧитательГеркин; КонецФункции diff --git "a/tests/fixtures/step_definitions/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\271\320\250\320\260\320\263.os" "b/tests/fixtures/step_definitions/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\271\320\250\320\260\320\263.os" new file mode 100644 index 0000000..64ef6d1 --- /dev/null +++ "b/tests/fixtures/step_definitions/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\271\320\250\320\260\320\263.os" @@ -0,0 +1,28 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯЗапускаюПадающийШагСПараметром"); + ВсеШаги.Добавить("ДоЭтогоШагаВыполнениеДойтиНеДолжно"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +//я запускаю падающий шаг с параметром "Первый падающий шаг" +Процедура ЯЗапускаюПадающийШагСПараметром(Знач ПарамСтрока) Экспорт + ВызватьИсключение СтрШаблон("ЯЗапускаюПадающийШагСПараметром-%1", ПарамСтрока); +КонецПроцедуры + +//до этого шага выполнение дойти не должно +Процедура ДоЭтогоШагаВыполнениеДойтиНеДолжно() Экспорт + ВызватьИсключение "ДоЭтогоШагаВыполнениеДойтиНеДолжно"; +КонецПроцедуры + diff --git "a/tests/fixtures/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\245\321\203\320\272\320\276\320\262.os" "b/tests/fixtures/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\245\321\203\320\272\320\276\320\262.os" new file mode 100644 index 0000000..6c0d167 --- /dev/null +++ "b/tests/fixtures/step_definitions/\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260\320\245\321\203\320\272\320\276\320\262.os" @@ -0,0 +1,54 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯЗаписываюВФайлЖурнала"); + + Возврат ВсеШаги; +КонецФункции + +Процедура ПередЗапускомСценария(Знач УзелОписанияСценария) Экспорт + ЯЗаписываюВФайлЖурнала(СтрШаблон("ПередЗапускомСценария-%1", УзелОписанияСценария.Тело)); +КонецПроцедуры + +Процедура ПослеЗапускаСценария(Знач УзелОписанияСценария) Экспорт + ЯЗаписываюВФайлЖурнала(СтрШаблон("ПослеЗапускаСценария-%1", УзелОписанияСценария.Тело)); +КонецПроцедуры + +// Реализация шагов + +//я записываю "ШагСценария" в файл журнала +Процедура ЯЗаписываюВФайлЖурнала(Знач СтрокаДляЖурнала) Экспорт + СтрокаИзЖурнала = ПрочитатьЖурнал(); + + ЗаписьФайла = Новый ЗаписьТекста(ПутьФайлаЖурнала(), "utf-8"); + + ЗаписьФайла.ЗаписатьСтроку(СтрШаблон("%1;%2", СтрокаИзЖурнала, СтрокаДляЖурнала)); + + ЗаписьФайла.Закрыть(); +КонецПроцедуры + +Функция ПрочитатьЖурнал() + ФайлЖурнала = Новый Файл(ПутьФайлаЖурнала()); + Если ФайлЖурнала.Существует() Тогда + + ЧтениеТекста = Новый ЧтениеТекста; + ЧтениеТекста.Открыть(ПутьФайлаЖурнала(),"UTF-8"); + + СтрокаИзЖурнала = ЧтениеТекста.ПрочитатьСтроку(); + ЧтениеТекста.Закрыть(); + Иначе + СтрокаИзЖурнала = ""; + КонецЕсли; + Возврат СтрокаИзЖурнала; +КонецФункции + +Функция ПутьФайлаЖурнала() + Возврат "ФайлЖурнала.log"; +КонецФункции // ПутьФайлаЖурнала() diff --git "a/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" "b/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" index a1976f1..1f96080 100644 --- "a/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" +++ "b/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.os" @@ -13,11 +13,11 @@ Возврат ВсеШаги; КонецФункции -Процедура ЯНичегоНеДелаю(ПарамСтрока) Экспорт +Процедура ЯНичегоНеДелаю(Знач ПарамСтрока) Экспорт ДобавитьВЖурнал("ЯНичегоНеДелаю", ПарамСтрока); КонецПроцедуры -Процедура НичегоНеПроисходит(ДругойПарамСтрока) Экспорт +Процедура НичегоНеПроисходит(Знач ДругойПарамСтрока) Экспорт ДобавитьВЖурнал("НичегоНеПроисходит", ДругойПарамСтрока); Ожидаем.Что(Журнал[КлючЖурнала], "Ожидали, что журнал выполнения будет правильным, а это не так").Равно("ЯНичегоНеДелаю<ПарамСтрока>;НичегоНеПроисходит<ДругойПарамСтрока>;"); diff --git "a/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" "b/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" index ced7f37..5bb008a 100644 --- "a/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" +++ "b/tests/fixtures/step_definitions/\320\241\321\202\321\200\320\276\320\272\320\276\320\262\321\213\320\265\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213_\320\222\321\201\320\265\320\232\320\273\321\216\321\207\320\265\320\262\321\213\320\265\320\237\320\276\320\273\321\217.os" @@ -15,19 +15,19 @@ Возврат ВсеШаги; КонецФункции -Процедура ЯНичегоНеДелаю(ПарамСтрока) Экспорт +Процедура ЯНичегоНеДелаю(Знач ПарамСтрока) Экспорт ДобавитьВЖурнал("ЯНичегоНеДелаю", ПарамСтрока); КонецПроцедуры -Процедура ВсеПутемИ(Парам1, Парам2) Экспорт +Процедура ВсеПутемИ(Знач Парам1, Знач Парам2) Экспорт ДобавитьВЖурнал("ВсеПутемИ", Парам1, Парам2); КонецПроцедуры -Процедура НиктоНичегоНеДелает(Парам1) Экспорт +Процедура НиктоНичегоНеДелает(Знач Парам1) Экспорт ДобавитьВЖурнал("НиктоНичегоНеДелает", Парам1); КонецПроцедуры -Процедура НичегоНеПроисходит(ДругойПарамСтрока) Экспорт +Процедура НичегоНеПроисходит(Знач ДругойПарамСтрока) Экспорт ДобавитьВЖурнал("НичегоНеПроисходит", ДругойПарамСтрока); Ожидаем.Что(Журнал[КлючЖурнала], "Ожидали, что журнал выполнения будет правильным, а это не так").Равно("ВсеПутемИ<ПарамДано><ПарамНеДано>;ЯНичегоНеДелаю<ПарамКогда>;НиктоНичегоНеДелает<ПарамИ>;НичегоНеПроисходит<ПарамТогда>;"); КонецПроцедуры diff --git "a/tests/fixtures/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\271\320\250\320\260\320\263.feature" "b/tests/fixtures/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\271\320\250\320\260\320\263.feature" new file mode 100644 index 0000000..321eb44 --- /dev/null +++ "b/tests/fixtures/\320\237\320\260\320\264\320\260\321\216\321\211\320\270\320\271\320\250\320\260\320\263.feature" @@ -0,0 +1,11 @@ +# language: ru + +Функционал: Выполнение фич + Как Разработчик + Я Хочу, чтобы у меня использовались подготовленные макеты/фикстуры + +Сценарий: После ошибочного шага следующие шаги сценария не выполняются + + Когда я запускаю падающий шаг с параметром "Первый падающий шаг" + промежуточный текст для проверки бага https://github.com/artbear/1bdd/issues/63 + Тогда до этого шага выполнение дойти не должно diff --git a/tests/gherkin-read-tests.os b/tests/gherkin-read-tests.os index 8660ff5..461439b 100644 --- a/tests/gherkin-read-tests.os +++ b/tests/gherkin-read-tests.os @@ -45,7 +45,7 @@ Процедура Тест_ДолженПрочитатьПростойФайлФичи() Экспорт - ВключитьОтладкуЧитателя(УровниЛога.Отладка); + // ВключитьОтладкуЧитателя(УровниЛога.Отладка); ФайлФичи = ПолучитьФайлФичи("БезПараметров"); diff --git a/tests/steps-generate-tests.os b/tests/steps-generate-tests.os index dafc51f..073f733 100644 --- a/tests/steps-generate-tests.os +++ b/tests/steps-generate-tests.os @@ -15,6 +15,8 @@ #Использовать asserts #Использовать tempfiles +#Использовать ".." + Перем юТест; Перем Лог; Перем ГенераторШагов; @@ -155,11 +157,9 @@ Лог = Логирование.ПолучитьЛог("bdd-gen-tests"); Лог.УстановитьУровень(УровниЛога.Отладка); - ЧитательГеркин = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "../src/gherkin-read.os")); - - ГенераторШагов = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "../src/bdd-generate.os")); - - ИсполнительБДД = ЗагрузитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "../src/bdd-exec.os")); + ЧитательГеркин = Новый ЧитательГеркин; + ГенераторШагов = Новый ГенераторШагов; + ИсполнительБДД = Новый ИсполнительБДД; КонецФункции