1. Функции/методы, объявление структуры
2. Встроенные типы
3. Настройка типов, дополнительный синтаксис и расширение объектов структур
4. Объявление новых локальных типов данных
Предоставляются следующие функции/методы:
Функции/методы, объявление структуры
- DataStructure.defineData(...): возвращает exotic object, описывающий структуру данных. Аргументами можно передавать любое количество обычных JS-объектов, они будут объединены в единую структуру (данные из последующих объектов могут перезаписать данные из предыдущих, если ключи будут совпадать). Также аргументами могут быть переданы другие объекты, объявленные через DataStructure.defineData(...).
- структура.generate(): сгенерировать данные по описанной структуре, где все типы, подразумевающие случайные значения, будут вычислены и присвоены к конечным фиксированным значениям. Удобно для генерации данных для тестирования, фэйковых данных или заполнения контентом.
- структура.validate(realData): если аргументом передан объект, то функция произведёт валидацию этого объекта в соответствии с описанной ранее структурой и напишет, где и в чём есть несоответствия.
- структура.toPhp(): вернёт валидный PHP-код, описывающий идентичную структуру данных как ассоциативный массив.
- структура.destroy(): приведёт к уничтожению структуры данных и пометке её содержимого как доступного для сборщика мусора. Попытки вызвать любые из вышеперечисленных методов или получить доступ по ссылке к вложенным объектам/значениям приведут к ошибке TypeError; это не относится к экземплярам данным, полученным с помощью метода .generate(), т.к. это совершенно независимые обычные объекты JS, поэтому они продолжат существовать после уничтожения объекта структуры данных. Также это не относится к изначальному объекту, описывающему структуру данных, если он был объявлен отдельной константой и затем передан аргументом в DataStructure.defineData(...), т.к. функция конструирует новую сущность, а не модифицирует передаваемый аргумент.
- oneOf(...args): возвращает одно случайное значение из списка переданных.
Встроенные типы
Чтобы использовать любой из дополнительных типов с характеристиками по умолчанию, достаточно написать его название, как если бы это был примитив или свойство глобального объекта ("строка", 123, undefined, window и т.п.). Конечное значение будет случайным. Полный список новых встроенных типов:
- bool: возвращает false либо true.
- int: возвращает случайное целое число от 0 до 1.
- float: возвращает случайное дробное число от 0 до 1.
- trend: возвращает объект со свойствами value и preValue, которые равны float, а также свойством trend, которое равно одному из значений: -1, 0, 1.
- trendInt: аналогично trend, но значения свойств value и preValue равны одному из трёх значений: 0, 1, 2.
- string: возвращает случайную строку из букв латиницы разного регистра, цифр и пробелов, длиной от 0 до 16 символов.
- words: возвращает случайную строку из "слов", состоящих из тех же значений и такой же длины, что и string по умолчанию; количество слов от 0 до 16 символов.
- uniq: возвращает неслучайное уникальное число (не индекс). Гарантируется возвращение одного и того же числа для одинаковых по порядку употреблений uniq в пределах всего объекта, описываемого через функцию DataStructure.defineData(...).
Настройка типов, дополнительный синтаксис и расширение объектов структур
Для некоторых типов можно указывать границы значений или дополнительные характеристики, которые можно свободно комбинировать между собой в любой порядке:
- string(4, 32), words(4, 32): минимальная и максимальная длина слова.
- string.chars('üöäß1234'), words.chars('üöäß1234'): набор символов, который используется для генерации строки/слов.
- words.number(4, 32): минимальное и максимальное количество слов в строке.
- int(100, 200), float(0.5, 1.5), trend(3.25, 3.5), trendInt(1, 4): минимальное и максимальное значение типа/решения.
Внутри описания структуры данных нельзя напрямую использовать конкатенацию, арифметические выражения, Object.assign(...) и любые другие взаимодействия новых типов (кроме uniq) с чем угодно (другими новыми типами или примитивами JS).
Для любого из новых типов или имеющихся в JS примитивов/объектов (кроме массивов, так как у них такой синтаксис используется для доступа к элементу массива) можно указать, что требуется массив фиксированной длины из значений такого вида, в том числе многомерный массив: coefs: float[4], statuses: int(0, 4)[2][4].
Для таких массивов можно задать случайную длину, используя один из новых типов данных: a: { b: 'c' }[int(4, 8)].
Внутри массивов, объявленных вышеприведённым способом, можно использовать тип uniq (см. описание во втором разделе), чтобы генерировать массивы объектов с уникальными значениями некоторых полей: myArray: { id: 'smth' + uniq, hello: 'world' }[12].
Можно получить случайное значение из фиксированного списка, используя специальную функцию: smth: oneOf(2, 'hello').
На самом объекте, объявленном через DataStructure.defineData(...), нельзя объявлять новые свойства или перезаписывать существующие.
Объявление новых локальных типов данных
Можно объявлять новые типы данных прямо внутри объекта; они будут работать только для объекта, внутри которого объявляются: $customType: { from: int(0, 9), to: int(0, 9) }, hello: customType, world: customType[4].
Если нужна поддержка опционального синтаксиса наподобие указания диапазона значений, то тип объявляется как функция: $x: function(a, b) { return int(a, b); }, test1: x(2, 4), test2: x.
Опциональные методы типов можно задать только для типов, возвращающих объекты или массивы (не примитивы типа string, number, boolean и т.п.); названия методов начинаются с "_", но при использовании этот символ уже не нужен. Опциональные методы принимают первым аргументом объект/массив, возвращаемый новым типом, и вторым аргументом – массив из передаваемых методу аргументов; метод должен возвращать новый или изменённый объект/массив нового типа. Пример:
$x: function(a, b) {
return {
name: 'fake object',
value: int(a, b),
_name: function(sourceObject, [newName]) {
return { ...sourceObject, name: newName };
},
};
},
test1: x,
test2: x(2, 4),
test3: x.name('another fake object'),
test4: x(3, 5).name('and one more'),
test5: x.name('Порядок вызова не важен')(3, 5),
Если требуется использование нескольких новых типов данных в разных объектах (например, по всему проекту), то можно упростить повторное объявление следующим образом:
// Объявляем где-то простой объект с нужными нам типами
const NEW_TYPES = DataStructure.defineData({
$customType1: { a: int(0, 3), b: float(0, 3) }[int(0, 30)],
$customType2: function(...a) { return { all: a, one: oneOf(a) }; }
});
// Переиспользуем объект
const MY_DATA = DataStructure.defineData(NEW_TYPES, {
smth: customType1[3],
abc: customType2('red', 'blue', 'green'),
});
1. Функции/методы, объявление структуры
2. Встроенные типы
3. Настройка типов, дополнительный синтаксис и расширение объектов структур
4. Объявление новых локальных типов данных