Создаем свою библиотеку для OneScript

Публикация № 791568 06.03.18

Приемы и методы разработки - OneScript

Как упаковать свою библиотеку в пакет? Что такое загрузчик и зачем он нужен? Как вообще создать свою библиотеку? Разбираемся на примере.

Оглавление

Введение. 2

Подготовка окружения. 2

Первый прототип. 2

Под капотом – загрузка библиотек. 6

Соглашение о структуре каталогов. 9

Первые тесты.. 11

Тестирование с помощью 1testrunner. 12

Классы и модули. 15

Перечисления. 19

Под капотом – lib.config. 21

Автодополнение. 22

Публичные и приватные классы и модули. 23

Сборка пакета. 25

Публикация пакета в хаб. 28

Заключение. 28

 

Введение

В своей предыдущей статье я рассказывал об имеющихся в экосистеме OneScript полезных библиотеках и приложениях. В этой статье мы попробуем написать свою библиотеку с нуля. Заранее извиняюсь за огромное количество упоминаний слова «библиотека» в тексте статьи :)

В рамках текущего повествования будут рассматриваться библиотеки, написанные на языке 1С. Написание библиотеки на C#/F#/VB.Net для OneScript заслуживает отдельной статьи.

Для начала напомню, что такое «библиотека». Библиотека – это особым образом упакованный сценарий (или набор сценариев), которые можно переиспользовать в других сценариях и подключать с помощью инструкции #Использовать. Инструкция #Использовать (в базовом варианте) умеет подключать библиотеки «по имени» и по пути к корневому каталогу библиотеки.

Подготовка окружения

Определимся с необходимым окружением.

  1. Естественно, нам понадобится сам движок - http://oscript.io/
  2. Разработку я буду вести в Visual Studio Code - https://code.visualstudio.com/
  3. Для упрощения редактирования сценариев OneScript у меня установлен плагин «Language 1C (BSL) Plugin)» - https://marketplace.visualstudio.com/items?itemName=xDrivenDevelopment.language-1c-bsl
  4. Для упрощения запуска и получения возможностей отладки, установим отладчик OneScript для Visual Studio Code. Если вы используете "стабильную" версию движка OneScript, то вы можете установить его через MarketPlace, встроенный в VSCode - имя пакета OneScript Debug. Если вы используете "ночную" версию движка, то необходимо скачать файл с расширением «vsix» со страницы http://oscript.io/download и установить его вручную через команду "Установка из VSIX" в VSCode

В рабочем каталоге создадим два новых подкаталога:

  • calculation – здесь будет жить наша библиотека
  • my_project – здесь будет жить проект, который использует библиотеку

Как и положено в любом how-to, мы будем писать библиотеку, складывающую и умножающую числа :) Еще и тестами ее покроем.

Первый прототип

Для начала заложим прототип нашей библиотеки. Для удобства я открою в VSCode рабочий каталог с двумя подкаталогами:

В корне каталога calculation создадим файл Вычислитель.os, который и будет отвечать за основную логику вычисления. В теле модуля расположим следующую нехитрую процедуру:

Функция Сложить(Слагаемое1, Слагаемое2) Экспорт

    Возврат Слагаемое1 + Слагаемое2;

КонецФункции

 

В корне каталога my_project создадим script.os, который будет изображать наше полезное прикладное ПО, использующее библиотеку calculation

Содержимое скрипта script.os:

#Использовать "../calculation"

 

Сумма = Вычислитель.Сложить(2, 2);

 

Сообщить(Сумма);

Разберемся построчно с написанным.

В первой строке используется специальная инструкция «Использовать», которая пытается найти и подключить библиотеку. Данной инструкции передается путь к корневому каталогу библиотеки, т.е. происходит подключение «по пути». Путь может быть как абсолютным, так и относительным. Для удобства мы используем относительный.

На следующей значащей строке происходит вызов функции «Сложить» у объекта Вычислитель. Разницу между модулями и классами и рассмотрим чуть позже, пока что можете запомнить, что это «модуль».

В последней строке мы выводим в консоль полученное значение.

Как же теперь это запустить? Есть несколько вариантов.

Классический – открыть консоль или встроенный в VSC терминал (сочетание клавиш ctrl-ё или команда «Посмотреть: Переключить интегрированный терминал») и выполнить скрипт напрямую с помощью интерпретатора oscript:

Второй вариант – с помощью встроенных команд по запуску скриптов. Нажмем F1 и в поисковой строке наберем «task». Выберем пункт «Задачи: Выполнить задачу»:

Появится еще одно окно, в котором нам нужно выполнить одну команду «oscript: OneScript: run»

Но мы же не просто так ставили отладчик?

Третий способ – запуск скрипта с помощью 1Script Debugger. Для начала нам надо создать специальный конфигурационный файл launch.json. Сделать это можно почти автоматически – нужно нажать в редакторе клавишу F5, в вывалившемся сверху окошке выбрать “1Script Debugger”. После этого в подкаталоге .vscode появится файл launch.json примерно со следующим содержимым:

Его назначение – хранить информацию о «конфигурациях запуска». Одну такую конфигурацию мы только что и создали.

Вернемся к нашему скрипту script.os и снова нажмем F5. После запуска на некоторое время должно появиться с окошком контроля выполнения кода (на скриншоте сверху слева) и в «Консоли отладки» (на скриншоте снизу) должно вывестись «4».

Если вы вообще не видите какого-либо окна снизу, то открыть «Консоль отладки» можно:

  • нажатием комбинации клавиш Ctrl+Shift+Y
  • выполнив команду «Посмотреть: Консоль отладки» из командного меню, вызываемого по клавише F1
  • выполнив команду «Вид» -> «Консоль отладки» из главного меню (вверху окна VSCode)
  • переключившись на вкладку «Отладка» (в левой части VSCode) и нажав кнопку «Консоль отладки»

Тем, кто успел открыть терминал, нужно будет вручную ткнуть по заголовку вкладки «Консоль отладки»

Точки останова тоже работают. И «табло» есть – тут оно называется «Контрольные значения». Оно не такое богатое, как в конфигураторе, но тоже очень сильно помогает.

Поздравляю, вы написали свою первую библиотеку! :)

Под капотом – загрузка библиотек

Постараемся понять, почему и как оно работает.

Пока мы не успели ничего сконфигурировать в нашей библиотеке - наш единственный сценарий «Вычислитель» лежит в корне каталога библиотеки. Когда мы «используем» с помощью соответствующей инструкции какую-либо библиотеку, OneScript выполняет определенную последовательность действий.

Сначала интерпретатор в корневом каталоге библиотеки ищет и пытается выполнить специальный «волшебный» сценарий package-loader.os – так называемый «загрузчик библиотек». Это специальный сценарий, который, как следует из его названия, занимается загрузкой библиотек – добавлением в область видимости классов и модулей, которые предоставляются библиотекой. В специальной процедуре-обработчике «ПриЗагрузкеБиблиотеки» среди параметров есть «СтандартнаяОбработка». Если в результате работы загрузчика она останется выставлена в «Истина» или файл package-loader.os в корне библиотеки вовсе отсутствует, то загрузка библиотеки переходит к следующему шагу.

На следующем шаге выполняется загрузчик «по умолчанию» - это такой же файл package-loader.os, который располагается в «системном каталоге библиотек». Значение системного каталога библиотек берется из параметра lib.system в файле oscript.cfg, расположенного либо в каталоге с точкой входа в приложение (первоначально запускаемый сценарий, например my_project/script.os) либо в каталоге самого интерпретатора oscript.exe. В базовом варианте (как у нас), lib.system начинает вести в место установки OneScript, подкаталог lib.

В моем случае, OneScript установлен в %USERPROFILE%/AppData/Local/ovm/current. Расположение каталогов и файлов на скриншоте ниже.

В загрузчике из системного каталога библиотек есть пара хитростей, о которых мы поговорим чуть позже. Сейчас важно знать, что и этот загрузчик не смог обработать нашу библиотеку, поэтому процесс загрузки библиотеки переходит к следующему (заключительному шагу)

На заключительном шаге загрузки библиотеки в дело вступает уже сам движок OneScript. Он максимально категоричен – ищет все файлы с расширением os в корневом каталоге библиотеки и подключает их как «модули». Именно это и произошло в нашем случае – файл Вычислитель из корня библиотеки был подключен как «модуль» и стал доступен для вызова и обращения «через точку» в сценарии script.os.

Схематично данный процесс можно представить так:

Чтобы развеять страх по поводу всей этой конструкции загрузчиков, попробуем вмешаться в процесс.

Создадим в каталоге calculation файл package-loader.os со следующим содержимым:

Процедура ПриЗагрузкеБиблиотеки(Путь, СтандартнаяОбработка, Отказ)

    

    Сообщить("Я - загрузчик библиотеки calculation!");

 

    СтандартнаяОбработка = Ложь;

 

    ПутьКМодулю = ОбъединитьПути(ТекущийСценарий().Каталог, "Вычислитель.os");

    ДобавитьМодуль(ПутьКМодулю, "Вычислитель");

 

КонецПроцедуры

 

В первой строке обозначена сигнатура метода. В параметре «Путь» передается путь к каталогу библиотеки, СтандартнаяОбработка – флаг продолжения выполнения последовательности действий по процессу загрузки, а Отказ – стандартный флаг сигнализирования об ошибках при загрузке библиотеки.

Вторая строка просто выводит сообщение в консоль.

Третья строка говорит интерпретатору OneScript, что текущий сценарий сможет загрузить эту библиотеку, и после его выполнения дополнительных действий совершать не требуется (см. схему).

В четвертой строке мы вычисляем путь к модулю, который хотим подключить. Для этого используются функции:

  • «ТекущийСценарий», возвращающая информацию о выполняемом в данный момент файле сценария (в том числе его расположение)
  • «ОбъединитьПути», складывающая различные части пути к файлам с учетом системных разделителей пути

В пятой строке вызывается процедура «ДобавитьМодуль», выполняющая фактическую регистрацию объекта в пространстве имен, с двумя параметрами:

  • Путь к подключаемому сценарию
  • Имя, под которым будет зарегистрирован объект

В пару к процедуре «ДобавитьМодуль» существует процедура «ДобавитьКласс»

Если мы снова откроем сценарий script.os и нажмем F5, то увидим в консоли отладки новое сообщение:

Наш загрузчик успешно отработал. Он не только вывел сообщение в консоль, но и корректно зарегистрировал модуль.

Соглашение о структуре каталогов

Рано или поздно библиотека выйдет за пределы одного-двух файлов в корне репозитория. Захочется вынести отдельно исходники библиотеки, тесты, документацию, служебные файлы… В конце концов, скоро мы и до классов дойдем, а стандартный загрузчик библиотек (на уровне интерпретатора) умеет подключать модули, но не классы.

К счастью, мы можем помочь «загрузчику библиотек» системного каталога библиотек, определенным образом расположив файлы сценариев в каталоге библиотеки.

Существует «соглашение о структуре каталогов» библиотеки. Все файлы *.os, которые располагаются в каталогах:

  • Классы
  • Classes
  • src/Классы
  • src/Classes

подключаются как «классы».

Аналогичным образом все файлы *.os, которые располагаются в каталогах:

  • Модули
  • Modules
  • src/Модули
  • src/Modules

подключатся как «модули».

Соглашение это не кровью написанное, а вполне определенным образом зашито в системном загрузчике библиотек. Если вы откроете файл package.loader (МестоУстановкиOneScript/lib/package-loader.os), то в процедуре «ПриЗагрузкеБиблиотеки» увидите вызов процедуры «ОбработатьСтруктуруКаталоговПоСоглашению». Именно в этой процедуре и указан список каталогов, в котором производится поиск.

Попробуем воспользоваться стандартным загрузчиком библиотек.

Для начала удалим файл package-loader.os из каталога calculation – он нам больше не нужен. Затем создадим подкаталог «src» и в нем подкаталог «Модули». Переместим туда файл «Вычислитель.os» и снова выполним (F5) сценарий script.os

Если все сделано без ошибок, то в консоли отладки будет выведена сумма двух чисел.

Убедимся, что это отработал системный загрузчик библиотек, а не очередная «магия» интерпретатора OneScript. Переключимся на вкладку «Терминал», запустим cmd (если по умолчанию терминал запускается в powershell) и выполним следующую команду:

(set OSLIB_LOADER_TRACE=1) && (oscript .\my_project\script.os)

Установка переменной среды OSLIB_LOADER_TRACE=1 заставит системный загрузчик библиотек активно информировать о своих действиях в консоль.

В выводе команды виден текст обработки каталогов «по соглашению».

Данный текст будет выводиться только при использовании OneScript версии 1.0.19 и новее, либо после обновления системного загрузчика библиотек актуальным текстом сценария

Первые тесты

Один мой друг показывал мне список задач (с реального проекта) по доработке с описанием задачи и способом приемки работ. Напротив большинства пунктов стояло загадочное «проверка визуально». Сейчас наша библиотека проверяется только «визуально», а это несколько несерьезно.

Попробуем добавить первый тест!

В каталоге библиотеки calculation создадим подкаталог tests и новый файл ПроверкаВычисления.os

Содержимое файла:

#Использовать asserts

#Использовать ".."

 

Результат = Вычислитель.Сложить(2, 2);

Ожидаем.Что(Результат).Равно(5);

 

 

В первой строке с помощью инструкции «Использовать» подключается библиотека asserts. Asserts – это библиотека, содержащая модули, помогающие в написании тестов. Она содержит два модуля: «Утверждения» и «Ожидаем» – для тестирования в unit- (модульное) и fluent- (текучее, цепное) стилях соответственно. Исходники библиотеки доступны по ссылке: https://github.com/oscript-library/asserts

Обратите внимание, имя библиотеки asserts указано без кавычек. Это способ подключения библиотек «по имени». Вычисление пути библиотеки делается очень просто – берется системный (и дополнительный, если он объявлен) каталог библиотек, к нему добавляется имя библиотеки – на выходе путь к каталогу библиотеки. Далее всё по той же схеме, что и при подключении библиотеки «по пути».

Второй строкой следует загадочная конструкция с использованием «..». В этом тоже нет никакой магии. Вспомним, что наш сценарий теста лежит в каталоге tests. Подключение библиотеки «по пути» умеет работать с относительными каталогами. Две точки – это обозначение родительского каталога. Складываем все три знания и получаем, что загрузчик библиотек будет пытаться загрузить каталог calculation, являющийся корнем нашей библиотеки. А в этом корне есть каталог src и вообще он всячески удовлетворяет «соглашению о структуре каталогов».

Таким образом на третьей строке нам становится доступен объект «Вычислитель» и его методы.

На четвертой строке применяется библиотека asserts. «Ожидаем» – это обращение к модулю этой библиотеки, функция «Что» устанавливает контекст проверки – мы проверяем результат работы функции «Сложить», функция «Равно» будет проверять переданное ей значение с сохраненным в контексте.

Если сейчас запустить этот сценарий (F5), то в «Консоли отладки» мы получим сообщение:

В этом сообщении есть две проблемы.

Пока у нас есть единственный тест, мы еще способны удержать в голове, что происходит. Когда количество тестов будет расти, стандартного сообщения об исключении начнет не хватать. Мы можем помочь сами себе, заполнив второй параметр в функции «Что» текстом сообщения с исключением:

Теперь помимо текста исключения от библиотеки «asserts» (о том, что 4 не равно 5) мы видим и наше дополнительное сообщение об ошибке.

Вторая проблема этого сообщения – тесты падают :) Причем падают по нашей вине. Поправим аргумент функции «Равно» на 4. После этого тест должен завершиться без ошибок.

Тестирование с помощью 1testrunner

Для тестирования библиотек сообществом разработано несколько фреймворков тестирования. Основные из них:

  • 1testrunner – для модульного и сценарного тестирования – является портом фреймворка xUnitFor1C для OneScript
  • 1bdd – для проверки поведения на основе требований в виде feature-файлов – не является прямым портом, но в целом похож на фреймворк Vanessa-Behavior

Данные фрейморки позволяют получать подробные отчеты о тестировании в нескольких форматах. Если эти фреймворки еще не установлены на вашем компьютере, их можно поставить через OneScript Package Manager, выполнив команду «opm install 1testrunner» и «opm install 1bdd» соответственно.

Адаптируем наш первый тест к использованию фреймворка 1testrunner. Для этого нам надо добавить в наш сценарий ПроверкаВычисления.os специальную функцию ПолучитьСписокТестов, возвращающую массив имен экспортных процедур, осуществляющих тестирование. А сами строки по проверке результата сложения перенести в эту новую процедуру. Дополнительно надо добавить две процедуры (ПередЗапускомТеста и ПослеЗапускаТеста), в которых при необходимости можно дополнительно сконфигурировать тест (нам пока нечего конфигурировать, поэтому мы не станем этого делать). Должно получиться что-то вроде такого:

#Использовать asserts

#Использовать ".."

 

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт

    ВсеТесты = Новый Массив;    

    ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоДваПлюсДваРавноЧетыре");

    

    Возврат ВсеТесты;

КонецФункции

 

Процедура ПередЗапускомТеста() Экспорт

КонецПроцедуры

 

Процедура ПослеЗапускаТеста() Экспорт

КонецПроцедуры

 

 

Процедура ТестДолжен_ПроверитьЧтоДваПлюсДваРавноЧетыре() Экспорт

    Результат = Вычислитель.Сложить(2, 2);

    Ожидаем.Что(Результат, "Ожидаем, что 2 + 2 = 4").Равно(4);

КонецПроцедуры

 

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

Как теперь все это запустить?

В редакторе VSCode (а точнее в плагине для поддержки языка 1C и OneScript) уже зашито несколько задач по тестированию. Нажмем F1 и в поисковой строке наберем «task». Выберем пункт «Задачи: Выполнить задачу»:

Появится еще одно окно, в котором нам нужно выполнить одну из команд «1testrunner»:

Если у вас открыт рабочий каталог сразу с двумя подкаталогами, то задача «Testing project» упадет с ошибкой, т.к. по умолчанию запускаются тесты из каталога tests, а у меня он вложен в подкаталог calculation. Конечно же, это можно подправить, нажав на шестеренку справа от задачи и скорректировав путь к тестам, но я просто выполню задачу «Testing current test-file».

Наградой нам станет «зеленая полоса» от фреймворка 1testrunner и сообщение о том, что все наши тесты (один :) ) пройдены.

Похожего результата можно добиться и запуская 1testrunner из терминала. Например, вот так можно запустить все тесты из каталога «tests»:

Классы и модули

В чем же разница между «модулями» и «классами», про которые я периодически рассказываю? Ключевых различий между ними два.

Первое различие - это способ инстанцирования объекта, другими словами – способ получения объекта, с которым можно начать что-то делать.

«Модуль» в контексте OneScript – это такой сценарий, обращаться к которому можно сразу же после запуска приложения. Если проводить аналогию с 1С, то это что-то вроде «общего модуля».

«Класс» в контексте OneScript – это такой сценарий, обращаться к которому можно только после получения конкретного «экземпляра» объекта с помощью ключевого слова Новый. По аналогии с 1С – это любые объекты: массив, структура, таблица значений. Только в OneScript эти классы не ограничены метаданными конфигурации, их можно создавать самому.

Второе различие вытекает из первого. Все сценарии в OneScript могут содержать переменные, объявленные в заголовке сценария с помощью ключевого слова Перем. Обращаю ваше внимание – в модулях тоже может содержаться несколько верхнеуровневых переменных.

Технически и модули и классы – это просто некие объекты в памяти, хранящие значения набора свойств и содержимое методов. Соответственно значения, сохраненные в свойствах (переменных) модуля, будут одинаковыми во всех местах вызова этого модуля (т.к. модуль инстанцируется один раз при начале работы системе). А значения свойств у классов будут различаться у каждого инстанцированного экземпляра класса.

Я рекомендую еще раз перечитать предыдущий абзац. И еще разок.

Возвращаемся к разработке нашей библиотеки - расширим ее потенциальные возможности.

Наш вычислитель планируется сделать очень умным. Например, он может уметь складывать числа, хранящиеся не только в памяти, но и на диске, или в SQL базе. Не спрашивайте зачем :)

Для хранения складываемых значений нам понадобится передавать в вычислитель не сами числа, а их хранилища. Для хранения чисел и способа их получения удобно использовать классы.

Следуя принципу Test-First сначала напишем тест на новую функциональность. Добавим в тестовый сценарий «ПроверкаВычисления» новую процедуру:

Процедура ТестДолжен_ПроверитьСложениеДвухЧиселВПамяти() Экспорт

    ЧислоВПамяти1 = Новый ЧислоВПамяти(1);

    ЧислоВПамяти2 = Новый ЧислоВПамяти(3);

 

    Результат = Вычислитель.Сложить(ЧислоВПамяти1, ЧислоВПамяти2);

    Ожидаем.Что(Результат, "Ожидаем, что сложение чисел из памяти работает").Равно(4);

КонецПроцедуры

В данном тесте я создаю два экземпляра (еще не разработанного) класса ЧислоВПамяти, передавая им в качестве параметра сохраняемое значение (единицу или тройку). В результате работы вычислителя мы должны получить четыре.

Не забудем добавить новый тест в функцию «ПолучитьСписокТестов».

Дополнительно добавим новый тест, проверяющий работу нашего класса. Создадим в каталоге calculation/tests новый файл ЧислоВПамяти.os

#Использовать asserts

#Использовать ".."

 

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт

    ВсеТесты = Новый Массив;    

    ВсеТесты.Добавить("ТестДолжен_ПроверитьСохранениеЗначенийВЧислоВПамяти");

    

    Возврат ВсеТесты;

КонецФункции

 

Процедура ПередЗапускомТеста() Экспорт

КонецПроцедуры

 

Процедура ПослеЗапускаТеста() Экспорт

КонецПроцедуры

 

Процедура ТестДолжен_ПроверитьСохранениеЗначенийВЧислоВПамяти() Экспорт

    ЧислоВПамяти = Новый ЧислоВПамяти(10);

    

    Ожидаем.Что(

        ЧислоВПамяти.Получить(),

        "Ожидаем, число 10 сохранилось в памяти объекта ЧислоВПамяти"

    ).Равно(10);

КонецПроцедуры

В данном тесте мы создаем новый экземпляр класса ЧислоВПамяти (передав ему начальное значение 10) и пытаемся получить это значение из класса.

После написания тестов мне уже примерно понятно, как должен работать новый класс. В завершение процесса написания тестов запустим прогон тестов через фреймворк 1testrunner:

1testrunner -runall .\calculation\tests\

В теле сообщения помимо текстов исключения видно общую статистику:

Наконец, переходим к разработке! В каталоге calculation/src создадим новый подкаталог Классы. В новом подкаталоге создадим файл ЧислоВПамяти.os – хранилище нашего нового класса.

В качестве реализации класса предлагаю такое решение «в лоб»:

Перем ХранимоеЗначение;

 

Процедура ПриСозданииОбъекта(УстанавливаемоеЗначение)

    ХранимоеЗначение = УстанавливаемоеЗначение;

КонецПроцедуры

 

Функция Получить() Экспорт

    Возврат ХранимоеЗначение;

КонецФункции

В качестве хранилища значения «числа в памяти» будет выступать переменная на уровне класса. С помощью специального процедуры «ПриСозданииОбъекта» (аналогия в 1С – ПриСозданииНаСервере у формы) мы описываем конструктор объекта. В нашем случае при вызове конструктора необходимо будет передать 1 параметр, который сохранится в переменной ХранимоеЗначение.

Конструктор объекта может и отсутствовать. Тогда инстанцирование объекта происходит без параметров, через вызов Новый ИмяКласса()

Функция «Получить» является способом возвращения значения, сохраненного в объекте.

Если снова запустить полный прогон тестов, то можно заметить, что количество прошедших тестов увеличилось – тест класса ЧислоВПамяти перестал выкидывать исключение.

Для «починки» последнего теста необходимо поправить получение значений слагаемых в модуле «Вычислитель». Откроем его (calculation/src/Модули/Вычислитель.os) и заменим реализацию функции сложить на следующую:

Функция Сложить(Слагаемое1, Слагаемое2) Экспорт

    РеальноеСлагаемое1 = ПолучитьРеальноеСлагаемое(Слагаемое1);

    РеальноеСлагаемое2 = ПолучитьРеальноеСлагаемое(Слагаемое2);

    Возврат РеальноеСлагаемое1 + РеальноеСлагаемое2;

КонецФункции

 

Функция ПолучитьРеальноеСлагаемое(Слагаемое)

    Если ТипЗнч(Слагаемое) = Тип("Число") Тогда

        РеальноеСлагаемое = Слагаемое;

    Иначе

        РеальноеСлагаемое = Слагаемое.Получить();

    КонецЕсли;

    

    Возврат РеальноеСлагаемое;

КонецФункции

Во-первых, добавим функцию ПолучитьРеальноеСлагаемое, которое будет возвращать число, которое нужно сложить. Если вдруг в Вычислитель передали реальное «число», то будет возвращаться сам параметр. Если же был передан какой-то объект, например, ЧислоВПамяти, будет выполняться попытка «получения» значения из этого объекта.

На этот раз запуск тестов должен показать три зеленых теста!

На сладкое, добавим немного «защитного программирования». Как автор класса ЧислоВПамяти, я хочу быть уверенным, что в конструктор объекта передается именно число, а не, например, строка.

Test-first! В тесте ЧислоВПамяти (calculation/tests/ЧислоВПамяти.os) добавим новый тест со следующим содержанием:

Процедура ТестДолжен_ПроверитьВыбросИсключенияПриСохраненииСтроки() Экспорт

    

    Попытка

        ЧислоВПамяти = Новый ЧислоВПамяти("Строка");

        ВызватьИсключение "Должен был произойти вызов исключения!";    

    Исключение

        Ожидаем.Что(

            ОписаниеОшибки(),

            "Описание ошибки содержит информацию о неверном аргументе"

        ).Содержит("Передан аргумент неверного типа");

    КонецПопытки;

    

КонецПроцедуры

 

В данном тесте используется трюк ожидания исключения. Для начала в попытке пытаемся создать новое ЧислоВПамяти, передав в конструктор «Строку». Если наш код работает корректно, то конструктор объекта выдаст исключение и мы провалимся в секцию «Исключение». Если же этого не произошло, мы явно вызываем исключение с текстом «Должен был произойти вызов исключения!». В любом случае мы попадаем в секцию «Исключение», где с помощью модуля из asserts «ожидаем», что ОписаниеОшибки(), содержит нужный нам текст.

Для “обычных” методов классов/модулей можно воспользоваться конструкцией Ожидаем.Что(Объект).Метод(ИмяМетода).ВыбрасываетИсключение(ТекстИсключения)

Запуск всех тестов добавит единичку в список провалившихся тестов.

Вернемся в класс ЧислоВПамяти (calculation/src/Классы/ЧислоВПамяти.os). Проверим тип аргумента с помощью библиотеки asserts:

#Использовать asserts

 

Перем ХранимоеЗначение;

 

Процедура ПриСозданииОбъекта(УстанавливаемоеЗначение)

    Ожидаем.Что(УстанавливаемоеЗначение, "Передан аргумент неверного типа").ИмеетТип("Число");

    ХранимоеЗначение = УстанавливаемоеЗначение;

КонецПроцедуры

 

Функция Получить() Экспорт

    Возврат ХранимоеЗначение;

КонецФункции

 Первым делом добавим подключение библиотеки в начале модуля с помощью инструкции «Использовать». Затем в конструкторе объекта (процедуре ПриСозданииОбъекта) с помощью модуля «Ожидаем» проверим, что переданное значение ИмеетТип Число. Как видите, библиотеку asserts можно использовать не только в тестировании, но при написании конкретного прикладного кода.

Теперь все тесты снова станут зелеными.

Подобным образом можно добавить хранение чисел в любом доступном хранилище, будь то файл на диске, облачный сервис с http-интерфейсом доступа или полноценная 1С с подключением через ComОбъект (пожалуйста, не надо так).

Перечисления

При разработке библиотек периодически возникает желание создать что-то вроде перечисления. Режимы работы, типы операций… Попробуем заложить фундамент расширяемости в нашу библиотеку, добавив универсальную функцию вычисления результата и перечисление, указывающее на тип операции вычисления.

В качестве хранилища значений перечисления будет выступать «модуль» с экспортными переменными. Вы же помните, что модуль может содержать переменные?

Создадим файл calculation/src/Модули/ТипыОпераций.os:

Содержимое файла:

Перем Сложение Экспорт;

Перем Умножение Экспорт;

 

Сложение = 0;

Умножение = 1;

Здесь в качестве «элементов перечисления» выступают экспортные переменные (свойства) модуля. Обращение к такому перечислению будет почти аналогично 1С:

ТипыОпераций.Сложение

В качестве значений переменных могут выступать любые данные, главное, чтобы «элементы перечисления» имели различные сравниваемые значения переменных – числа, строки, булево и т.д.

Обращаю внимание, что данные значения «перечисления» по сути являются изменяемыми данными, прикладная библиотека может выполнить код в духе:

ТипыОпераций.Сложение = 123;

И он выполнится без ошибок – свойство-то экспортное, то есть доступное всем и каждому. Для исключения побочных эффектов можно применять методику get-еров:

  • у значений элементов перечисления убирается ключевое Экспорт
  • под каждый элемент перечисления создается функция (обычно одноименная), возвращающая значение элемента перечисления. Например, ТипыОпераций.Сложение()

Такой подход позволит обеспечить неизменяемость значений перечисления, но и перестает выглядеть как собственно «перечисления». Какой способ применять – выбирать вам.

После создания перечисления добавим универсальную функцию вычисления результата.

Test first! :)

Откроем файл с тестами (calculation/tests/ПроверкаВычисления.os) и добавим два новых теста:

Процедура ТестДолжен_ПроверитьСложениеЧерезУниверсальнуюФункцию() Экспорт

    Результат = Вычислитель.ВыполнитьВычисление(ТипыОпераций.Сложение, 2, 2);

    Ожидаем.Что(Результат, "Ожидаем, что сложение через универсальную функцию работает").Равно(4);

КонецПроцедуры

 

Процедура ТестДолжен_ПроверитьУмножениеЧерезУниверсальнуюФункцию() Экспорт

    Результат = Вычислитель.ВыполнитьВычисление(ТипыОпераций.Умножение, 2, 3);

    Ожидаем.Что(Результат, "Ожидаем, что умножение через универсальную функцию работает").Равно(6);

КонецПроцедуры

В данных тестах мы предполагаем, что в модуле «Вычислитель» появится универсальная функция ВыполнитьВычисление, в которую можно передать тип операции и параметры-числа.

Перейдем к реализации данной функции. В файл calculation/src/Модули/Вычислитель.os добавим пару новых функций и напишем их реализации:

Функция ВыполнитьВычисление(ТипОперации, Операнд1, Операнд2) Экспорт
    Если ТипОперации = ТипыОпераций.Сложение Тогда
        Возврат Сложить(Операнд1, Операнд2);
    ИначеЕсли ТипОперации = ТипыОпераций.Умножение Тогда
        Возврат Умножить(Операнд1, Операнд2);
    Иначе
        ВызватьИсключение "Неизвестный тип операции";
    КонецЕсли;
КонецФункции
 
Функция Умножить(Множитель1, Множитель2) Экспорт
    РеальныйМножитель1 = ПолучитьРеальноеСлагаемое(Множитель1);
    РеальныйМножитель2 = ПолучитьРеальноеСлагаемое(Множитель2);
    Возврат РеальныйМножитель1 * РеальныйМножитель2;
КонецФункции

В функции «ВыполнитьВычисление» первым делом пытаемся понять, что за тип операции нам передали. В зависимости от типа операции вызываем ту или иную функцию вычисления. Рефакторинг функции «ПолучитьРеальноеСлагаемое» (ее имя и имена переменных внутри) оставлю на вас – теперь же тесты есть, уже не страшно. Кстати, они снова зеленые!

Под капотом – lib.config

К сожалению, «соглашение именования каталогов» не всегда применимо. С ростом нашей библиотеки нам может понадобится по-другому группировать файлы в каталогах. Ортодоксальные разработчики именуют файлы латиницей, при этом хотят обращаться модулям и классам на кириллице. Или вообще сделать двуязычные имена модулей/классов – не дублировать же файлы на диске!

Для решения этих задач (и не только перечисленных) в «системный загрузчик библиотек» было добавлено еще одно «соглашение» о правилах загрузки. На этот раз оно не завязано на структуру каталогов – описание типов подключаемых сценариев (и их системных) имен описывается в отдельном текстовом файле lib.config, расположенном в корневом каталоге библиотеки:

Описание имеющихся модулей и классов выглядит так:

<package-def>
    <class name="ЧислоВПамяти" file="src/Классы/ЧислоВПамяти.os"/>
    <module name="Вычислитель" file="src/Модули/Вычислитель.os"/>
    <module name="ТипыОпераций" file="src/Модули/ТипыОпераций.os"/>
</
package-def>

Структура файла говорит сама за себя. Расскажу о нескольких важных моментах:

1)      Для системного загрузчика библиотек проверка на наличие lib.config в корне библиотеки является более приоритетным, чем загрузка по «соглашению о структуре каталогов». Если библиотека содержит файл lib.config, то подключение сценариев по «соглашению» выполняться не будет.

2)      Файл lib.config может содержать несколько строчек, ведущих на один и тот же файл. Например, вы можете добавить английский синоним модулю Вычислитель – для этого надо всего лишь скопировать строчку с подключением «вычислителя» и в качестве значения атрибута name указать Calculation. OneScript подключит этот сценарий два раза, создав два разных объекта в памяти – для английского синонима и для русского.

3)      Более того, вы можете подключать один и тот же файл сценария как разные типы – модуль и класс. Тогда в глобальном пространстве имен прикладного сценария будет доступен и «модуль» (со своим отдельным хранилищем значений переменных), так и инстанцирование новых объектов через конструктор, с использованием ключевого слова «Новый». Этим, кстати, пользуется библиотека tempfiles, предназначенная для управления создаваемыми временными файлами. По имени ВременныеФайлы доступен «глобальный менеджер временных файлов», единый для всех точек обращения к этому модулю, а при необходимости, вы можете дополнительно проинициализировать «Новый МенеджерВременныхФайлов». С точки зрения реализации это один и тот же файл сценария, просто два раза прописанный в lib.config.

Автодополнение

Редактор Visual Studio Code (а точнее плагин Language 1C (BSL) для него) поддерживает базовые возможности по автодополнению методов классов и модулей, предоставляемых библиотеками.

Для работы системы автодополнения нужно выполнить три шага:

  1. На вашей локальной машине должен стоять пакет-приложение oscript-config. Поставить его можно из хаба пакетов с помощью команды opm install oscript-config. Поставили один раз и забыли.
  2. Библиотека, от которой вы хотите получить автодополнение, должна содержать файл lib.config. Именно этот файл ищет плагин для VSCode и по нему определяет, какие файлы (и их содержимое) надо добавлять в систему автодополнения.
  3. Объект, к которому идет обращение, должен называться так же, как он подключается к системе типов самого движка OneScript. Если с модулями проблем нет (кому придет в голову сохранять ссылку на модуль в другой переменной), то с классами есть небольшая засада. Для получения автодополнения имен методов, например, у класса УправлениеКонфигуратором (из пакета v8runner), имя переменной должно равно УправлениеКонфигуратором.

Т.е. после нажатия на Ctrl+Space в таком коде (после точки) вы сможете увидеть список его методов:

УправлениеКонфигуратором = Новый УправлениеКонфигуратором();

УправлениеКонфигуратором.

Аналогично для и для нашего класса ЧислоВПамяти. Пользователи смогут пользоваться автодополнением только если будут именовать переменные так же, как и класс (привет, Массив = Новый Массив!)

Пункт, который зависит от нас, как от авторов библиотеки – наличие файла lib.config – уже выполнен, так что у вас есть все шансы получить благодарного пользователя не только потому, что ваша библиотека работает, но и потому, что ей удобно пользоваться.

Публичные и приватные классы и модули

Все типы классов и модулей, подключаемых в OneScript, попадают в «глобальную область видимости». Т.е. будучи подключенными раз, они будут доступных из всех закоулков вашего прикладного приложения (в рамках одного запуска, естественно). Поэтому понятие «приватных», т.е. невидимых для внешнего пользователя классов и модулей в OneScript несколько размыто.

Однако, с учетом работающей системы автодополнения, мы можем хотя бы ограничить количество классов и модулей, доступных к выбору по Ctrl+Space.

В качестве примера реализации такого сокрытия возьмем библиотеку fluent - https://github.com/nixel2007/oscript-fluent/tree/v0.3.1

Если обратиться к содержимому lib.config в корне библиотеки, то можно увидеть два объекта – один класс и один модуль:

Однако, дерево файлов выглядит интереснее:

На верхнем уровне каталога src созданы уже стандартные подкаталоги Классы и Модули, в которых находятся файлы, объявленные в lib.config. Дополнительно в src располагается каталог «internal», в котором так же есть свои «классы» и «модули».

Если открыть, например, файл src/Классы/ПроцессорКоллекций, то в заголовке файла можно увидеть такую конструкцию:

После подключения стандартных библиотек «по имени» происходит подключение каталога “../internal”.

Вся эта конструкция как-то работает, при этом «внутренние» класс и модуль (с постфиксом «служебный» недоступны в системе автодополнения. Попробуем разобраться, что же происходит.

  1. При «использовании» пакета fluent системный загрузчик библиотек считывает содержимое файла lib.config
  2. По содержимому lib.config движок OneScript подключает класс ПроцессорКоллекции и модуль ПроцессорыКоллекций
  3. При инициализации указанных класса и модуля происходит использование библиотеки «../internal» «по пути»
  4. Системный загрузчик библиотек анализирует содержимое каталога «../internal», не находит там файла lib.config, но определяет соответствие «соглашению о структуре каталогов»
  5. Движок OneScript подключает «служебные» модуль и класс.

Параллельно этому процессу система автодополнения Visual Studio Code анализирует файл lib.config, располагающийся в корне библиотеки fluent и подключает описанные там класс и модуль.

Таким образом с одной стороны (со стороны движка OneScript) у нас есть полностью работающая библиотека с четырьмя сценариями – двумя классами («публичным» и «служебным») и двумя модулями (так же «публичным» и «служебным»). А со стороны системы автодополнения было прочитано только два сценария – один класс и один модуль.

«Честным» сокрытием внутренних классов это можно назвать с большой натяжкой, но выкручиваемся как можем :)

Еще раз напоминаю, что все классы и модули подключаются в глобальную область видимости. Как следствие возможен конфликт имен между различными библиотеками. Не стоит называть «внутренний» модуль каким-то очень распространенным именем, например, «Параметры». Назовите его «Параметры_ИмяВашейБиблиотеки». Вам как разработчику не составит труда при реализации вашей внутренней логики печатать на пару символов больше, а остальные пользователи скажут вам «спасибо» за бесконфликтную библиотеку.

Сборка пакета

Итак, наш пакет готов к тому, чтобы поделиться им с сообществом. Большинство хороших и известных библиотек собираются в специальное «пакеты» и публикуются в хаб пакетов. «Пакет» - это особым образом упакованный zip-архив, который OneScript Package Manager (opm) умеет собирать, публиковать и устанавливать.

Все хорошие пакеты помимо содержимого в виде кода имеют описание библиотеки в файле README.md. Md – это расширение файлов, обозначающее язык MarkDown. Практически все репозитории, которые вы встретите на просторах GitHub, имеют описание в виде файла README.md.

Создадим в корне каталога calculation файл README.md примерно со следующим содержимым:

Если выполнить команду «Markdown: Открыть область предварительный просмотра» (или нажать комбинацию клавиш ctrl-k, затем v), то откроется отдельное окно, в котором отобразится итоговый внешний вид файла MarkDown:

Для сборки пакета нам необходимо заполнить специальное «описание пакета» - небольшой сценарий, в котором указываются данные о пакете.

Создадим в каталоге calculation новый файл с именем packagedef (без расширения) – package definition:

Содержимое файла:

Описание.Имя("calculation")

    .Версия("1.0.0")

    .Автор("Nikita Gryzlov")

    .АдресАвтора("nixel2007@gmail.com")

    .Описание("Арифметические операции для любителей функционального программирования")

    .ВерсияСреды("1.0.17")

    .ВключитьФайл("src")

    .ВключитьФайл("lib.config")

    .ВключитьФайл("README.md")

    .ЗависитОт("asserts", "0.3.1")

;

Эти эльфийские письмена на самом деле не делают ничего магического. Packagedef – это специальный файл, который используется opm при сборке пакета. Это обычный сценарий на языке 1C/OneScript. При его инициализации в область видимости добавляется экземпляр класса «ОписаниеПакета», содержимое этого класса можно подсмотреть в репозитории opm (https://github.com/oscript-library/opm/blob/master/src/%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D1%8B/%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5%D0%9F%D0%B0%D0%BA%D0%B5%D1%82%D0%B0.os). В файле packagedef мы вызываем методы этого класса, которые занимаются заполнением содержимого.

Пробежимся по используемым функциям:

  • Описание пакета обычно начинается с указания идентификатора (имени) библиотеки. Далее в произвольном порядке следуют все остальные поля
  • Версия пакета (библиотеки)
  • Автор
  • Email автора для связи
  • Текстовое описание пакета
  • ВерсияСреды – минимальная версия движка OneScript, требуемая для использования данного пакета
  • ВключитьФайл – пути к файлам и каталогам, которые необходимо добавить в пакет при сборке. Сюда же можно добавить файлы примеров использования, любую документацию и вообще все, что вы пожелаете загрузить на конечный компьютер пользователя
  • ЗависитОт – зависимости нашего пакета от других пакетов. Класс ЧислоВПамяти использует библиотеку asserts для проверки типов переданных значений, поэтому нам нужно указать эту зависимость в описании пакета. При установке нашего пакета opm будет контролировать наличие всех зависимостей и доустанавливать нужные при необходимости

Если начать копаться во внутренностях opm, то можно выяснить, что если packagedef будет содержать вызовы функций «ОпределяетКласс» и «ОпределяетМодуль», то файл lib.config сформируется автоматически. Т.е. в целом мы могли его и не формировать руками, а описать в едином месте в packagedef. Однако, если структура каталогов библиотеки не будет удовлетворять «соглашению о структуре каталогов», то нам самим будет тяжелее ее разрабатывать и тестировать, т.к. тесты и отладчик не будут знать, какие классы и откуда загружать. Поэтому моя личная рекомендация – формируем файл руками и «включаем» его в packagedef.

Описание пакета готово, попробуем собрать наш пакет! Для этого выполним команду opm build с указанием пути к каталогу, в котором располагается файл packagedef:

На выходе получаем файл ospx – собранный пакет. При желании его можно открыть любым zip-архиватором и поисследовать.

Что мы можем делать с этим пакетом? Как минимум мы можем его установить!

У opm есть команда install, среди параметров которой есть параметр -f, отвечающий за путь к файлу пакета, который необходимо установить. Если он не указан, то пакет скачивается с хаба пакетов в облаке, иначе берется указанный файл.

Если OneScript у вас установлен «как обычно» в Program files, то может потребоваться запуск командной строки с правами администратора.

Выполнение этой команды привело к установке пакета calculation в системный каталог пакетов. Физически это выглядит так:

Создался новый каталог по имени пакета (calculation), в каталоге расположены файлы, которые мы указали как «включаемые» в packagedef.

Зачем это все? Теперь мы можем «использовать» нашу библиотеку «по имени»! Вернемся в сценарий my_project/script.os и заменим строку «использования» библиотеки с «пути» (с кавычками и двумя точками) на подключение «по имени» (без кавычек и каких-либо путей):

Сценарий продолжает работать и выдавать в консоль цифру «4», а значит, мы сделали все правильно.

Если переоткрыть редактор VSCode (или выполнить команду Language 1C (BSL): Update reference cache), то наша библиотека отобразиться Синтакс-Помощнике, в разделе oscript-library:

Публикация пакета в хаб

Наша библиотека собрана в пакет, дело осталось за малым – поделиться библиотекой со всем миром! Конечно же, можно скидывать файл ospx коллегам в скайп/гиттер/слак, но лучше разместить его в хабе пакетов. Для этого нужно сделать три вещи:

  1. Исходники библиотеки должны быть опубликованы на GitHub. Я не буду подробно останавливаться на принципах работы с гитом, на ИС есть достаточно базовых статей на эту тему. От вас не требуется ничего сверхтяжелого – создать новый репозиторий на GitHub, закоммитить все содержимое библиотеки и запушить изменения.
  2. Постучаться по различным каналам связи к администраторам организации oscript-library (https://github.com/oscript-library) на GitHub или написать в Gitter-канал библиотеки пакетов (https://gitter.im/EvilBeaver/oscript-library) – дать ссылку на ваш реп и попросить добавить в хаб пакетов. Через некоторое время вам скажут «угумс!» и вы можете приступать непосредственно к публикации.
  3. Публикация пакета производится так же с помощью утилиты opm.

Теперь подробнее о публикации. Публикация выполняется с помощью команды opm push. Как следует из справки нам необходимо указать два или три параметра:

--file – это путь к файлу ospx. Можно использовать маску поиска.

--token – токен авторизации с сервера GitHub. Новый токен можно создать новый на странице https://github.com/settings/tokens. Сохраните значение токена, если планируете им пользоваться в дальнейшем, GitHub отображает его только в момент генерации, после обновления страницы значение пропадет.

--channel – канал публикации. Если вы публикуете изменения из git-репозитория и ветки master, то указание этого параметра не требуется.

Обычно, я выполняю публикацию с помощью следующей команды:

opm push --file *.ospx --token МойГитхабТокен

После успешного выполнения команды в Gitter-канале oscript-library появится примерно такое сообщение:

И самое главное, что пакет станет доступен в хабе пакетов http://hub.oscript.io.

Заключение

Thats all, folks! Надеюсь, этот гайд поможет вам влиться в увлекательный мир создания библиотек для OneScript, и количество нового и полезного начнет стремительно расти :)

Финальное содержимое каталога calculation можно найти в моем репозитории на GitHub - https://github.com/nixel2007/infostart-calculation

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Infactum 309 06.03.18 14:38 Сейчас в теме
Вот это правильная статья, в отличие от того, что в последнее время в топе болтается.
Perfolenta; Kosstikk; nvv1970; Soloist; Liris; troubleshooter; bulpi; o4karek; antonst1; fancy; CSiER; kuntashov; Evil Beaver; +13 Ответить
2. nixel 1302 06.03.18 14:45 Сейчас в теме
31. пользователь 19.04.18 11:33
Сообщение было скрыто модератором.
...
32. пользователь 19.04.18 16:02
Сообщение было скрыто модератором.
...
33. пользователь 19.04.18 20:31
Сообщение было скрыто модератором.
...
34. пользователь 20.04.18 01:27
Сообщение было скрыто модератором.
...
36. пользователь 20.04.18 10:43
Сообщение было скрыто модератором.
...
37. пользователь 20.04.18 19:42
Сообщение было скрыто модератором.
...
38. пользователь 21.04.18 01:14
Сообщение было скрыто модератором.
...
39. пользователь 22.04.18 00:44
Сообщение было скрыто модератором.
...
40. пользователь 23.04.18 04:29
Сообщение было скрыто модератором.
...
43. пользователь 25.04.18 08:28
Сообщение было скрыто модератором.
...
44. пользователь 26.04.18 04:01
Сообщение было скрыто модератором.
...
3. Evil Beaver 7776 06.03.18 15:44 Сейчас в теме
Фундаментально, ага!

Для получения автодополнения имен методов, например, у класса УправлениеКонфигуратором (из пакета v8runner), имя переменной должно равно УправлениеКонфигуратором.


Вот у меня точно помню, что переменная называлась иначе, а подсказка в VSC все равно срабатывала. Может в VSC уже и выведение типа переменной сделано, а мы пропустили?
4. nixel 1302 06.03.18 16:00 Сейчас в теме
(3)

Фундаментально, ага!


Прелестно, прелестно! :)

Вот у меня точно помню, что переменная называлась иначе, а подсказка в VSC все равно срабатывала. Может в VSC уже и выведение типа переменной сделано, а мы пропустили?


А ты уверен, что у тебя после точки выводились нужные тебе процедуры и функции, а оно не совпало (случайно) с каким-то зарегистрированным классом/модулем?
5. lustin 06.03.18 16:58 Сейчас в теме
(0) теперь для чистоты эксперимента - делаем ставки сколько новых библиотек появится ;-).

Круто кстати - особенно BPMN
nvv1970; creatermc; nixel; +3 Ответить
6. nixel 1302 06.03.18 17:16 Сейчас в теме
(5) ну, ты жаловался периодически на тему "как же создать новую библиотеку". вот тебе полноценный гайд :D
olegtymko; +1 1 Ответить
29. Steelvan 269 12.03.18 15:57 Сейчас в теме
(6) ... полноценное руководство
Perfolenta; +1 2 Ответить
22. bulpi 209 09.03.18 18:04 Сейчас в теме
Не по теме публикации, чисто потрепаться. Одному мне кажется, что все эти тесты - не более, чем игры взрослых мальчиков в солдатики? Подозреваю, что таких как я , большинство, но все молчат, боясь показать свою "немодность" и "непродвинутость". Любая проблема должна быть решена наипростейшим образом, в том числе проблема тестирования. "Визуальное" тестирование и есть наипростейшее решение. А вот это все Ожидаем.Что(Результат).Равно(5)
- "горе от ума". Возможно, это нужно в ооо...чень больших проектах, которых примерно 0.01% от общего количества. За всю жизнь ни разу в таких не участвовал.
23. nixel 1302 09.03.18 22:38 Сейчас в теме
(22) любой более-менее серийный/серьёзный продукт надо тестировать. Когда твой скрипт запускается больше, чем один раз и обрастает функциональностью, когда от него зависит работа продакшн контура, его развёртывание и более сложное использование - без тестирования любой баг в логике влетает во вполне ощутимые деньги.
Точно так же и с конфигурациями. Bdd/Tdd спасают производство и ускоряют разработку (хотя для большинства этот пункт звучит удивительно и непонятно)
nvv1970; artbear; +2 Ответить
24. nixel 1302 09.03.18 22:41 Сейчас в теме
(22) визуальное тестирование, которое производится более двух раз, обычно уже дороже, чем написание автоматизированного теста. А отсутствие тестирования обычно дороже, чем его отсутствие :) простая мотивация.
Perfolenta; artbear; +2 Ответить
25. nixel 1302 10.03.18 00:55 Сейчас в теме
(24) а наличие тестирования дороже, чем его отсутствие *
26. nixel 1302 10.03.18 11:09 Сейчас в теме
(25) и с третьей попытки - отсутствие тестирования дороже, чем его наличие :)

P.S. Вчера был тяжёлый день
AntonH851; +1 Ответить
27. dmpas 10.03.18 20:28 Сейчас в теме
(22)
игры взрослых мальчиков в солдатики

это как велосипедный шлем, как наколенники при катании на роликах, как очки и перчатки во время ремонта, как строительные ботинки со стаканом в носке. "Крутые парни с улицы" смотрят на всё это свысока, но профессионалы без этого за дело не берутся.
SagittariusA; Perfolenta; Kosstikk; nvv1970; Evil Beaver; troubleshooter; artbear; nixel; JohnyDeath; +9 Ответить
46. Perfolenta 201 07.07.19 14:35 Сейчас в теме
(27) на счет ботинков со стаканом в носке подтверждаю на 100%, т.к. лично видел, как эти ботинки спасли человеку ступни...
28. vano-ekt 850 11.03.18 08:25 Сейчас в теме
(22)
игры взрослых мальчиков в солдатики

не обращай внимания, они даже ИС читают curl'ом , а не хромом
зачем нажимать целых две кнопки ctrl+F в браузере, когда можно вызвать программу с десятью опциями?
те же яйца, но в другой корзинке IDE
7. artbear 1424 06.03.18 17:39 Сейчас в теме
Отличная статья.

Зачем это все? Теперь мы можем «использовать» нашу библиотеку «по имени»! Вернемся в сценарий my_project/script.os и заменим строку «использования» библиотеки с «пути» (с кавычками и двумя точками) на подключение «по имени» (без кавычек и каких-либо путей):

а теперь попробуйте доработать библиотеку в исходниках, запустить тесты и получить прохождение тестов не своих исходников, а уже установленной библиотеки.

Предлагаю написать, что
+ мы можем «использовать» нашу библиотеку «по имени»
+ для этого создадим новый сценарий вне каталога исходников библиотеки и обратимся к нашей установленной библиотеке

и также лучше указать, что #Использовать ".." должно быть первым в списке #Использовать для исключения проблем разработки
alex_bob; +1 Ответить
8. nixel 1302 06.03.18 18:06 Сейчас в теме
(7) новый сценарий и так вне каталога библиотеки располагается, это внешний проект, созданный в начале статьи. в чем вопрос?
9. artbear 1424 06.03.18 18:16 Сейчас в теме
(8) Упс, не увидел на скриншоте.
Значит, заработался, пора домой!
16. artbear 1424 07.03.18 11:15 Сейчас в теме
(8) Предлагаю указать, что #Использовать ".." должно быть первым в списке #Использовать для исключения дальнейших проблем разработки
10. AlexWhite 195 06.03.18 20:28 Сейчас в теме
11. Brawler 438 06.03.18 21:09 Сейчас в теме
Завидую тем, кто не погряз в учетных дебрях типовых и тренирует пытливые мозги!))
Осознаю, что наблюдаю со стороны за рождением чего-то значительного.
Так держать!!!
nvv1970; nixel; +2 Ответить
12. kuntashov 422 06.03.18 23:09 Сейчас в теме
Заранее извиняюсь за огромное количество упоминаний слова «библиотека» в тексте статьи :)


$ curl -s -L https://infostart.ru/public/791568 | iconv -f cp1251 -t utf8 | grep -o 'библио*' | wc -l
139
Kosstikk; nvv1970; artbear; JohnyDeath; Evil Beaver; lustin; nixel; +7 Ответить
13. nixel 1302 07.03.18 01:24 Сейчас в теме
(12) кажется, что это новый рекорд :D
kuntashov; +1 Ответить
18. Evil Beaver 7776 07.03.18 14:02 Сейчас в теме
(12) Эта строчка заслуживает отдельной гик-медали. Как посчитать количество вхождений слова в интернет-статье одной строчкой консоли, используя только стандартные утилиты unix ))
bulpi; artbear; +2 Ответить
19. dmpas 07.03.18 14:48 Сейчас в теме
(18)
я позанудствую, но слово "Библиотека" есть в разделах в меню слева. Ещё наверняка в каких-нибудь мета-тэгах.
20. Evil Beaver 7776 07.03.18 16:22 Сейчас в теме
(19) Пулреквест в oneliner от Кунташова?
kuntashov; +1 Ответить
21. kuntashov 422 07.03.18 17:18 Сейчас в теме
(19) Я подумал, что в данном случае погрешностью в пару случаев можно пренебречь :)
14. new_user 07.03.18 08:57 Сейчас в теме
15. nixel 1302 07.03.18 09:29 Сейчас в теме
(14) спасибо, Саш :) ждать от тебя библиотеку?)
30. new_user 21.03.18 16:23 Сейчас в теме
(15) да, простенькую, но полезную)
17. Samarkan63 07.03.18 11:47 Сейчас в теме
Интересная тема, понаблюдаю )
35. пользователь 20.04.18 01:27
Сообщение было скрыто модератором.
...
41. Gureev 23.04.18 16:07 Сейчас в теме
Может не очень в тему, подскажите, можно ли OneScript собрать в exe'шник?
42. nixel 1302 23.04.18 17:31 Сейчас в теме
(41) да, можно. oscript -make путь/к/главному/файлу/os имя.exe
45. пользователь 20.02.19 16:29
Сообщение было скрыто модератором.
...
47. alex_bob 239 31.07.19 09:26 Сейчас в теме
Отличная статья. Многое проясняет. А что делает oscript, если в двух разных используемых библиотеках встретятся модули или классы с одинаковыми названиями?
48. nixel 1302 31.07.19 09:32 Сейчас в теме
(47) в зависимости от настроек и флагов в переменных среды.
Либо упадёт с исключением, либо загрузит одно из них.
49. ahyahy 56 03.12.19 18:36 Сейчас в теме
Спасибо! Статью обязательно прочитаю/дочитаю. Вот библиотека для создания gui. Приходите на https://onescriptgui.teriy.com/ Пока она там находится. Классов - 176, свойств - 1073, методов - 557, перечислений - 63. Основана на KiXforms.NET v3.2.16.0 написанной Shawn Tassie. Правда её причесать как следует надо. Вот эта статья как раз то, что надо. Исходный код позже будет, рук не хватает и теперь времени не стало хватать.
50. VKislitsin 870 11.09.22 12:57 Сейчас в теме
Никита, спасибо за статью!
Подскажите, пожалуйста, а как в VSC отключить анализ "Когнитивная сложность, Цикломатическая сложность"? Попробовал в настройках плагина выключить параметр "Language-1c-bsl: Language Server Enabled" - перестала распознаваться структура модуля (Области).
Прикрепленные файлы:
51. nixel 1302 11.09.22 13:20 Сейчас в теме
(50) добрый день.

Линзы цикломатической и когнитивной сложностей предоставляет не плагин, а bsl language server, который конфигурируется через файл .bsl-language-server.json в корне проекта.

Описание конфигурационного файла доступно в документации к bsl ls: https://1c-syntax.github.io/bsl-language-server/features/ConfigurationFile/

Так же в vscode должно работать автодополнение по этому файлу. Если вдруг не работает, добавьте в файл параметр $schema вручную.

Вас интересует секция настроек codeLens, где можно либо отключить указанные линзы, либо увеличить порог срабатывания для их показа.
VKislitsin; +1 Ответить
Оставьте свое сообщение

См. также

Прокси хранилища 1С (IIS, OneScript) Промо

Групповая разработка (Git, хранилище) OneScript DevOps и автоматизация разработки Платформа 1С v8.3 Платформа 1С v8.3 Россия Россия Бесплатно (free) Бесплатно (free)

Избавляемся от версионной зависимости, проверяем комментарии, вызываем веб-хуки, делаем красивые пути. И все это на привычном IIS и понятном OneScript.

08.12.2022    4129    kamisov    19    

reperr - автоматическая регистрация ошибок для 8.3.17+

OneScript Управление задачами (Task Manager) Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

Представляю вашему вниманию приложение для автоматической регистрации и обработки ошибок, которые возникают при работе в информационных базах на платформе 1С:Предприятие 8.3.17+

04.02.2021    7083    ovcharenko.di    11    

Автоматическое сравнение-объединение баз данных с мини-конфигурацией

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

Представляю вашему вниманию скрипт на OneScript для автоматического сравнения-объединения по правилам ("мержевания") конфигураций нескольких баз с мини-конфигурацией.

14.10.2019    4056    artkor    2    

АИТП. Подсистема взаимодействия с рабочими серверами OneScript

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

В статье описан механизм взаимодействия конфигурации АИТП с рабочими серверами OneScript.

22.05.2019    6107    blackhole321    33    

Разворачиваем рабочий сервер OneScript для конфигурации АИТП

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

В статье описана методика развертывания рабочего сервера OneScript для конфигурации АИТП, на ОС CentOS 7.

09.05.2019    7109    blackhole321    0    

Автоматизируй это!

OneScript Инструменты администратора БД Бесплатно (free) Бесплатно (free)

Здравствуйте. Меня зовут Виталий Онянов. Я работаю в компании ФТО. Мы занимаемся внедрением и поддержкой ERP-систем, в том числе и на 1С. Сегодня я хотел бы поделиться нашим опытом автоматизации своих задач и рассказать о том, какие регламентные задания мы настраиваем на серверах наших клиентов. Возможно, кому-то покажется, что это совсем простые и очевидные вещи, но я в своей работе периодически вижу разработчиков, которые делают какие-то задачи руками изо дня в день, и мне бы хотелось донести до них мысль о том, что многие из этих задач можно и нужно автоматизировать.

02.07.2018    25063    Tavalik    12    

Добавляем онлайн-чат в web-приложение OneScript

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

В статье рассмотрено подключение онлайн-чата к web-приложению на основе http-сервисов OneScript

24.06.2018    8244    blackhole321    1    

Сказ про то, как я DevOps-ом занимался (OneScript, Deployka, Jenkins)

OneScript DevOps и автоматизация разработки Платформа 1С v8.3 Платформа 1С v8.3 Конфигурации 1cv8 Конфигурации 1cv8 ИТ-компания ИТ-компания Бесплатно (free) Бесплатно (free)

Решаем задачу: автоматизировать обновление тестовых баз 1С из хранилища конфигурации при появлении в нём новых изменений. Данная статья родилась в муках хождения по граблям и поиска безопасного форватора среди подводных камней. Изложение постарался представить в виде инструкции для новичка, в которой собрал всё, с чем пришлось столкнуться. Сам я не DevOps-ер, ни на что не претендую, просто делюсь опытом :)

17.06.2018    27490    stas_ganiev    37    

Макеты в http-сервисах OneScript

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

В статье описана библиотека, реализующая механизм макетов в http-сервисах OneScript, аналогично платформе 1С:Предприятие.

03.06.2018    9094    blackhole321    1    

Перечисления в http-сервисах OneScript

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

В статье описывается библиотека, реализующая механизм перечислений в http-сервиах OneScript, аналогичный механизму платформы 1С:Предприятие

03.06.2018    8598    blackhole321    13    

Сборка, тестирование, доставка приложения на onescript с помощью gitlab-ci

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Конфигурации 1cv8 Конфигурации 1cv8 Бесплатно (free) Бесплатно (free)

Сборка, тестирование, доставка приложения на onescript с помощью gitlab-ci на примере портирования на onescript функции daСклонение.

14.05.2018    14756    pallid    7    

TMSSQL - работа с базами данных MS SQL Server в скриптах на OneScript и из командной строки

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

Представляю вашему вниманию библиотеку TMSQL для работы с базами данных на MS SQL Server. Библиотека подключается в качестве модуля или класса в скрипты, написанные на OneScript, а также может работать как независимое консольное приложение.

26.04.2018    16830    Tavalik    22    

Обзор имеющихся библиотек OneScript

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Бесплатно (free) Бесплатно (free)

Экосистема OneScript активно развивается. Количество пользователей данного интерпретатора и имеющихся библиотек неуклонно растет, количество решаемых проблем - тоже. Однако остро встает вопрос некоторой разобщенности и размазанности информации по имеющимся библиотекам, их функциональности и проблемам, которые они решают. Данная статья призвана навести порядок в этой теме.

14.11.2017    56924    nixel    88    

Вебинтерфейс для OneScript и 1С

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Россия Россия Бесплатно (free) Бесплатно (free)

Пример создания вебинтерфейса для OneScript с использованием библиотеки UfaScript.osb

30.06.2017    14785    andreosh    7    

OneScript и Ajax. POST-запрос и мои дальнейшие планы с фантазиями о будущем

OneScript Платформа 1С v8.3 Платформа 1С v8.3 Россия Россия Бесплатно (free) Бесплатно (free)

Моя библиотека для OneScript (версия 3.0 от 09.06.2017 см.GitHab UfaScript) https://github.com/andreosh/UfaScript теперь позволяет посылать POST-запросы на сервер без использования сторонних библиотек типа jquery.

09.06.2017    18506    andreosh    3