diff --git a/.gitignore b/.gitignore index 76a7b40..f622095 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.ospx tests.xml coverage/* - +bdd-log.xml tests-reports/* \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 3f3affb..64716c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,20 +21,12 @@ addons: sonarqube: true jdk: - - oraclejdk8 + - openjdk11 before_install: # Load cached docker images - if [[ -d $HOME/docker ]]; then ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load"; fi -before_script: - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build - -after_script: - - ./cc-test-reporter after-build --prefix "/home/travis/build/khorevaa/cli/coverage/" --exit-code $TRAVIS_TEST_RESULT - before_cache: # Save tagged docker images - > @@ -50,7 +42,7 @@ script: - grep 'Результат прогона тестов <Да>' /tmp/test.log after_success: # - bash <(curl -s https://codecov.io/bash) - # - ./sonar-qube.sh + - ./sonar-qube.sh cache: directories: diff --git a/README.md b/README.md index 466e0bb..5fcd01f 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Процедура ВыполнитьПриложение() - Приложение = Новый КонсольноеПриложение("cli", "Помощник генерации приложения на основании шаблона cli"); + Приложение = Новый КонсольноеПриложение("cli", "Помощник генерации приложения на основании шаблона cli", ЭтотОбъект); Приложение.Версия("v version","1.0.0"); Приложение.ДобавитьКоманду("i init", "Инициализация структуры нового приложения", Новый КомандаInit); @@ -72,6 +72,10 @@ КонецПроцедуры // ВыполнениеКоманды() +Процедура ВыполнитьКоманду(Знач КомандаПриложения) Экспорт + КомандаПриложения.ВывестиСправку(); +КонецПроцедуры + /////////////////////////////////////////////////////// Попытка @@ -383,7 +387,7 @@ cli поддерживает создание команд и подкоманд ```bsl Приложение = Новый КонсольноеПриложение("testapp", "Выполняет полезную работу"); -КомандаAve = Приложение.ДобавитьПодкоманду("a ave", "Команда ave", КлассРеализацииПодкоманды); +КомандаAve = Приложение.ДобавитьКоманду("a ave", "Команда ave", КлассРеализацииПодкоманды); ``` * Первый аргумент, наименование команды, которое необходимо будет вводить для запуска @@ -393,7 +397,7 @@ cli поддерживает создание команд и подкоманд cli поддерживает указание псевдонимов команд. Для примера: ```bsl -КомандаAve = Приложение.ДобавитьПодкоманду("start run r", "Команда start", КлассРеализацииПодкоманды); +КомандаAve = Приложение.ДобавитьКоманду("start run r", "Команда start", КлассРеализацииПодкоманды); ``` Псевдонимы для команды будут `start`, `run`, и`r` - можно использовать любой из них. diff --git "a/features/\320\227\320\260\320\277\321\203\321\201\320\272 \320\261\320\265\320\267 \320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" "b/features/\320\227\320\260\320\277\321\203\321\201\320\272 \320\261\320\265\320\267 \320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" new file mode 100644 index 0000000..8e8b3cc --- /dev/null +++ "b/features/\320\227\320\260\320\277\321\203\321\201\320\272 \320\261\320\265\320\267 \320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.feature" @@ -0,0 +1,25 @@ +# language: ru + +Функционал: Создание проекта + Как разработчик + Я хочу запускать приложение + +Контекст: + Дано Я очищаю параметры команды "oscript" в контексте + +Сценарий: Запуск приложения без параметров + + Когда Я выполняю команду "oscript" с параметрами "<КаталогПроекта>/tests/fixtures/ТестовоеПриложение.os" + И я вижу в консоли вывод + """ + Приложение: my-tests + """ + И Код возврата команды "oscript" равен 1 + +Сценарий: Получение версии приложения + Когда Я выполняю команду "oscript" с параметрами "<КаталогПроекта>/tests/fixtures/ТестовоеПриложение.os -v" + И я вижу в консоли вывод + """ + 0.1.0 + """ + И Код возврата команды "oscript" равен 0 diff --git a/sonar-project.properties b/sonar-project.properties index c6d2b50..2322944 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,6 +1,6 @@ # must be unique in a given SonarQube instance -sonar.projectKey=opensource-cli -sonar.organization=sonar-opensource-add +sonar.projectKey=cli +# sonar.organization=sonar-opensource-add # this is the name displayed in the SonarQube UI sonar.projectName=Command Line Interface for OScript diff --git a/sonar-qube.sh b/sonar-qube.sh index f56f2f2..1271e0f 100755 --- a/sonar-qube.sh +++ b/sonar-qube.sh @@ -1,8 +1,8 @@ temp=`cat packagedef | grep ".Версия(" | sed 's|[^"]*"||' | sed -r 's/".+//'` version=${temp##*|} - if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then + sonar-scanner \ -Dsonar.host.url=https://sonar.silverbulleters.org \ -Dsonar.analysis.mode=issues \ @@ -14,9 +14,9 @@ if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then elif [ "$TRAVIS_BRANCH" == "develop" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then sonar-scanner \ - -Dsonar.host.url=https://sonar.silverbulleters.org \ + -Dsonar.host.url=https://sonar.oscript.ru \ -Dsonar.login=$SONAR_TOKEN \ -Dsonar.projectVersion=$version\ -Dsonar.scanner.skip=false fi -fi \ No newline at end of file +fi diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\320\270\320\227\320\260\320\262\320\265\321\200\321\210\320\265\320\275\320\270\320\265\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\320\270\320\227\320\260\320\262\320\265\321\200\321\210\320\265\320\275\320\270\320\265\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" index 890a16f..e8f7b2f 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\320\270\320\227\320\260\320\262\320\265\321\200\321\210\320\265\320\275\320\270\320\265\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\320\270\320\227\320\260\320\262\320\265\321\200\321\210\320\265\320\275\320\270\320\265\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" @@ -11,8 +11,6 @@ // Функция Поиск(Аргументы, КонтекстПоиска) Экспорт - КонтекстПоиска.СбросОпций = Истина; - Результат = Новый Структура("РезультатПоиска, Аргументы", Истина, Аргументы); Возврат Результат; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" index 3272a11..29ed20a 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -117,6 +117,17 @@ Возврат Описание; КонецФункции +// Функция возвращает строку использования (спек) команды +// +// Возвращаемое значение: +// Cтрока - строка использования (спек) текущей команды +// +Функция ПолучитьСтрокуИспользования() Экспорт + + Возврат ?(Не ПустаяСтрока(Спек), Спек, СформироватьСтандартнуюСтрокуИспользования()); + +КонецФункции + // Функция возвращает значение опции по переданному имени/синониму опции // // Параметры: @@ -402,7 +413,7 @@ Если ОшибкаЧтения Тогда Лог.КритичнаяОшибка("Ошибка чтения параметров команды"); ВывестиСправку(); - Возврат; + ВызватьИсключение "Ошибка чтения параметров команды"; КонецЕсли; ВыполнитьДействиеКоманды("ПередВыполнениемКоманды"); @@ -493,13 +504,7 @@ Лог.Отладка("Входящий спек: %1", Спек); - СтрокаИспользования = Спек; - - Если ПустаяСтрока(СтрокаИспользования) Тогда - - СтрокаИспользования = СформироватьСтандартнуюСтрокуИспользования(); - - КонецЕсли; + СтрокаИспользования = ПолучитьСтрокуИспользования(); Лог.Отладка("Разбираю строку использования с помощью лексера"); @@ -856,7 +861,7 @@ Если Не КлассПроверки = КлассРеализации Тогда - Возврат Новый РефлекторОбъекта(КлассРеализации); + Возврат Новый РефлекторОбъекта(КлассПроверки); Иначе @@ -935,7 +940,7 @@ Если Не ПустаяСтрока(СтрокаТаблицы.ПодробноеОписание) Тогда - СтрокаНаименования = СтрШаблон(" %2%1%", Символы.Таб, СтрокаТаблицы.Наименование); + СтрокаНаименования = СтрШаблон(" %2%1", Символы.Таб, СтрокаТаблицы.Наименование); ДлинаДополнения = СтрДлина(СтрокаНаименования) + ДобавочнаяДлинаДополнения; МассивСтрок = СтрРазделить(СтрокаТаблицы.ПодробноеОписание, Символы.ПС, Ложь); @@ -1101,7 +1106,24 @@ СтандартнаяСтрокаИспользования = ""; Лог.Отладка("Количество опций строки: %1", Опции.Количество()); - Если Опции.Количество() > 0 Тогда + ЕстьОбязательнаяОпция = Ложь; + Для каждого Опция Из Опции Цикл + + ИмяОпции = Опция.Ключ.НаименованияПараметров[0]; + КлассОпции = Опция.Ключ; + + Если КлассОпции.ПолучитьОбязательностьВвода() Тогда + ЕстьОбязательнаяОпция = Истина; + КонецЕсли; + + ДополнитьИмяАргументаМассива(ИмяОпции, КлассОпции); + ДополнитьИмяАргументаНеобязательного(ИмяОпции, КлассОпции); + + СтандартнаяСтрокаИспользования = СтандартнаяСтрокаИспользования + ИмяОпции + " "; + + КонецЦикла; + + Если Не ЕстьОбязательнаяОпция И Опции.Количество() > 0 Тогда СтандартнаяСтрокаИспользования = "[ОПЦИИ] "; КонецЕсли; @@ -1118,7 +1140,7 @@ ДополнитьИмяАргументаМассива(ИмяАргумента, КлассАргумента); ДополнитьИмяАргументаНеобязательного(ИмяАргумента, КлассАргумента); - Лог.Отладка("Добавляю аргумет <%1> в спек <%2>", ИмяАргумента, СтандартнаяСтрокаИспользования); + Лог.Отладка("Добавляю аргумент <%1> в спек <%2>", ИмяАргумента, СтандартнаяСтрокаИспользования); СтандартнаяСтрокаИспользования = СтандартнаяСтрокаИспользования + ИмяАргумента + " "; КонецЦикла; @@ -1238,8 +1260,13 @@ НоваяЗапись.ПеременнаяОкружения = ПараметрСправки.ПеременнаяОкружения; НоваяЗапись.СкрытьЗначение = ПараметрСправки.СкрытьЗначение; НоваяЗапись.НаименованияПараметров = ПараметрСправки.НаименованияПараметров; - НоваяЗапись.Значение = ПараметрСправки.ЗначениеВСтроку(); - + + Если НЕ ПараметрСправки.УстановленаИзПеременнойОкружения Тогда + + НоваяЗапись.Значение = ПараметрСправки.ЗначениеВСтроку(); + + КонецЕсли; + КонецЦикла; Возврат ТаблицаДанных; @@ -1285,4 +1312,4 @@ КонецПроцедуры -Лог = Логирование.ПолучитьЛог("oscript.lib.cli_command"); \ No newline at end of file +Лог = Логирование.ПолучитьЛог("oscript.lib.cli_command"); diff --git a/tasks/test.os b/tasks/test.os index 80b7cea..36de811 100644 --- a/tasks/test.os +++ b/tasks/test.os @@ -71,13 +71,13 @@ ФичиПрошли = Истина; -// Попытка -// ФичиПрошли = ПрогнатьФичи(); -// Исключение -// ФичиПрошли = Ложь; -// Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно -// |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); -// КонецПопытки; +Попытка + ФичиПрошли = ПрогнатьФичи(); +Исключение + ФичиПрошли = Ложь; + Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно + |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); +КонецПопытки; Если Не ТестыПрошли Или Не ФичиПрошли Тогда ВызватьИсключение "Тестирование завершилось неудачно!"; diff --git "a/tests/fixtures/\320\242\320\265\321\201\321\202\320\276\320\262\320\276\320\265\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\320\265.os" "b/tests/fixtures/\320\242\320\265\321\201\321\202\320\276\320\262\320\276\320\265\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\320\265.os" new file mode 100644 index 0000000..2cc65f1 --- /dev/null +++ "b/tests/fixtures/\320\242\320\265\321\201\321\202\320\276\320\262\320\276\320\265\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\320\265.os" @@ -0,0 +1,32 @@ +#Использовать "../../src/core" + +Процедура ВыполнитьПриложение() + + Приложение = Новый КонсольноеПриложение( "my-tests", + "Мое описание"); + Приложение.Версия("v version", "0.1.0"); + + // Приложение.ДобавитьКоманду( + // "m make", "", + // Новый ); + + // Приложение.УстановитьОсновноеДействие(ЭтотОбъект); + Приложение.Запустить(АргументыКоманднойСтроки); + +КонецПроцедуры // ВыполнениеКоманды() + +// Процедура ВыполнитьКоманду(Знач КомандаПриложения) Экспорт +// КомандаПриложения.ВывестиСправку(); +// КонецПроцедуры + +Попытка + + ВыполнитьПриложение(); + ЗавершитьРаботу(0); + +Исключение + + Сообщить(ОписаниеОшибки()); + ЗавершитьРаботу(1); + +КонецПопытки; \ No newline at end of file diff --git "a/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" "b/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" index 8b6c10c..6002abb 100644 --- "a/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" +++ "b/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" @@ -39,7 +39,7 @@ ИменаТестов.Добавить("ТестДолжен_СтандартнуюСтрокуИспользования"); ИменаТестов.Добавить("ТестДолжен_СтандартнуюСтрокуИспользования_МассивАргументов"); ИменаТестов.Добавить("ТестДолжен_СтандартнуюСтрокуИспользования_МассивАргументовНесколькоАргументов"); - + ИменаТестов.Добавить("ТестДолжен_СтандартнуюСтрокуИспользования_ОбязательнаяОпция"); // ИменаТестов.Добавить("ТестДолжен_СложныеСлучаиФормированияСтрокиИспользования"); ИменаТестов.Добавить("ТестДолжен_ПроверитьВыводСправки"); @@ -354,6 +354,37 @@ КонецПроцедуры +Процедура ТестДолжен_СтандартнуюСтрокуИспользования_ОбязательнаяОпция() Экспорт + + Команда = ПодготовитьТестовуюКоманду(); + + ОбычныйОпция = Команда.Опция("z", , "Необязательная опция").ТСтрока(); + ОпцияМассив = Команда.Опция("e env", Новый Массив, "Тестовый необязательный массив опций").ТМассивСтрок(); + ARG2 = Команда.Аргумент("ARG2", "", "Тестовый простой необязательный аргумент").ТМассивСтрок(); + + СтрокаИспользования = СокрЛП(Команда.ПолучитьСтрокуИспользования()); + Утверждения.ПроверитьРавенство(СтрокаИспользования, "[ОПЦИИ] -- ARG2...", "Результат <СтрокаИспользования> должны совпадать"); + + + Команда = ПодготовитьТестовуюКоманду(); + + ОбычныйОпция = Команда.Опция("z", , "Необязательная опция").ТСтрока(); + ОпцияМассив = Команда.Опция("e env", Новый Массив, "Тестовый обязательный массив опций").ТМассивСтрок().Обязательный(Истина); + ARG2 = Команда.Аргумент("ARG2", "", "Тестовый простой необязательный аргумент").ТМассивСтрок(); + + СтрокаИспользования = СокрЛП(Команда.ПолучитьСтрокуИспользования()); + Утверждения.ПроверитьРавенство(СтрокаИспользования, "[-z] -e... -- ARG2...", "Результат <СтрокаИспользования> должны совпадать"); + + + Команда = ПодготовитьТестовуюКоманду(); + + ARG2 = Команда.Аргумент("ARG2", "", "Тестовый простой необязательный аргумент").ТМассивСтрок(); + + СтрокаИспользования = СокрЛП(Команда.ПолучитьСтрокуИспользования()); + Утверждения.ПроверитьРавенство(СтрокаИспользования, "-- ARG2...", "Результат <СтрокаИспользования> должны совпадать"); + +КонецПроцедуры + Процедура ТестДолжен_ПроверитьВыводСправки() Экспорт Спек = ""; @@ -383,6 +414,7 @@ Аргументы.Добавить("-e=Знач1"); Аргументы.Добавить("-e=Знач2"); Аргументы.Добавить("-e=Знач3"); + Аргументы.Добавить("--"); Аргументы.Добавить("-v"); Аргументы.Добавить("ARG2"); Аргументы.Добавить("run");