В этом репозитории находятся материалы тестового задания «Напишите линтер» для 15-й Школы разработки интерфейсов (осень 2019, Москва).
Вам нужно написать линтер, проверяющий, что структура блоков интерфейса соответствует правилам. В качестве решения предоставьте исходный код и запускаемый файл линтера.
Запускаемый файл должен находиться в репозитории в папке build
и должен называться linter.js
. Его размер не должен превышать 1 MB. Код этого файла должен создавать в глобальной области видимости функцию lint
. Эта функция должна одинаково работать в браузере и Node.JS. Для работы линтера не должны требоваться внешние зависимости, находящиеся вне файла linter.js
.
Мы не ограничиваем вас в выборе технологий, фреймворков и библиотек. Пожалуйста, для каждого выбранного инструмента напишите небольшое обоснование — зачем он нужен в вашем проекте и почему именно он.
Линтер получает на вход строку (string
), которая описывает структуру блоков интерфейса в формате JSON. Формат описания блоков — такой же, как в первом задании. Например:
const json = `{
"block": "form",
"content": [
{
"block": "form",
"elem": "label",
"content": {
"block": "text",
"mods": { "size": "xl" }
}
},
{
"block": "input",
"mods": { "size": "xxl" }
}
]
}`;
На выходе линтер должен выдавать массив ошибок. Каждый элемент массива должен описывать одну ошибку (нарушение правила) и иметь поля:
error
— текст ошибки (для каджого правила выберите текст ошибки на свое усмотрение).code
— код ошибки (указан для каждого правила в его описании).location
— информация о положении ошибочного блока в исходной строке. В полеlocation
должны быть поляstart
иend
, каждое из которых содержит номер строки и символа в ней. Нумерация строк и символов начинается с 1.
Для указанного выше примера результ работы линтера будет таким:
[
{
"code": "FORM.INPUT_AND_LABEL_SIZES_SHOULD_BE_EQUAL",
"error": "Подписи и поля в форме должны быть одного размера",
"location": {
"start": { "line": 12, "column": 9 },
"end": { "line": 15, "column": 10 }
}
}
]
Если ошибок нет, линтер должен вернуть пустой массив.
Чтобы уменьшить нагрузку на преподавателей, проверяющих задания, мы хотим предварительно проверять задания автотестами. Если задание не прошло автотесты, оно будет отправлено на доработку и не дойдет до ручной проверки.
Для автотестов важна файловая структура вашего репозитория и формат выходных/выходных данных. Пожалуйста в точности выполните требования, указанные выше!
-
Все инпуты, кнопки и тексты в лейблах в блоке формы должны быть одного размера (c одинаковым значением модификатора
size
). Эталонным считается размер первого элемента формы. Например:{ "block": "form", "content" [ { "block": "form", "elem": "label", "content": { "block": "text", "mods": { "size": "l" } } }, // правильно { "block": "input", "mods": { "size": "l" } } // неправильно { "block": "input", "mods": { "size": "s" } } ] }
Код ошибки:
FORM.INPUT_AND_LABEL_SIZES_SHOULD_BE_EQUAL
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного блокаform
в строке. -
Вертикальный внутренний отступ контентного элемента формы
content
должен задаваться с помощью микса на него элемента формыitem
со значением модификатораspace-v
на 2 шага больше эталонного размера (например, для размера l таким значением будет xxl).{ "block": "form", "content": { "block": "form", "elem": "content", "content": { "block": "input", "mods": { "size": "l" } }, // правильно "mix": [{ "block": "form", "elem": "item", "mods": { "space-v": "xxl" } }] // неправильно "mix": [{ "block": "form", "elem": "item", "mods": { "space-v": "xl" } }] } }
Код ошибки:
FORM.CONTENT_VERTICAL_SPACE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаcontent
в строке. -
Горизонтальный внутренний отступ контентного элемента должен задаваться с помощью модификатора
space-h
элемента формыitem
на 1 шаг больше эталонного размера.{ "block": "form", "content": { "block": "form", "elem": "content", "content": { "block": "input", "mods": { "size": "l" } }, // правильно "mix": [{ "block": "form", "elem": "item", "mods": { "space-h": "xl" } }] // неправильно "mix": [{ "block": "form", "elem": "item", "mods": { "space-h": "xxl" } }] } }
Код ошибки:
FORM.CONTENT_HORIZONTAL_SPACE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаcontent
в строке. -
Строки формы (в которые складываются лейбл и инпут) помечаются элементом формы
content-item
и должны отбиваться между собой с помощью модификатора нижнего отступа со значением модификатораindent-b
элемента формыitem
на 1 шаг больше эталонного размера.{ "block": "form", "content": { "block": "form", "elem": "content", "content": [ // правильно { "block": "form", "elem": "content-item", "mix": [{ "block": "form", "elem": "item", "mods": { "indent-b": "xl" } }], "mods": { "indent-b": "xl" }, "content": { "block": "input", "mods": { "size": "l" } } }, // неправильно { "block": "form", "elem": "content-item", "mix": [{ "block": "form", "elem": "item", "mods": { "indent-b": "l" } }], "content": { "block": "input", "mods": { "size": "l" } } }, { "block": "form", "elem": "content-item", "content": { "block": "input", "mods": { "size": "l" } } } ] } }
Код ошибки:
FORM.CONTENT_ITEM_INDENT_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаcontent-item
в строке. -
Все текстовые блоки в заголовке формы (элемент
header
) должны быть со значением модификатораsize
на 2 шага больше эталонного размера.{ "block": "form", "content": [ { "block": "form", "elem": "header", "content": [ // правильно { "block": "text", "mods": { "size": "xxl" } }, // неправильно { "block": "text", "mods": { "size": "xl" } } ] }, { "block": "input", "mods": { "size": "l" } } ] }
Код ошибки:
FORM.HEADER_TEXT_SIZE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного блокаtext
в строке. -
Вертикальный внутренний отступ заголовка формы должен быть задан с помощью микса на него элемента формы
item
со значением модификатораspace-v
, равным эталонному размеру.{ "block": "form", "content": [ // правильно { "block": "form", "elem": "header", "mix": [ { "block": "form", "elem": "item", "mods": { "space-v": "l" } } ] }, // неправильно { "block": "form", "elem": "header", "mix": [ { "block": "form", "elem": "item", "mods": { "space-v": "s" } } ] }, { "block": "input", "mods": { "size": "l" } } ] }
Код ошибки:
FORM.HEADER_VERTICAL_SPACE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаheader
в строке. -
Горизонтальный внутренний отступ должен быть на 1 шаг больше эталонного размера.
{ "block": "form", "content": [ // правильно { "block": "form", "elem": "header", "mix": [ { "block": "form", "elem": "item", "mods": { "space-h": "xl" } } ] }, // неправильно { "block": "form", "elem": "header", "mix": [ { "block": "form", "elem": "item", "mods": { "space-h": "s" } } ] }, { "block": "input", "mods": { "size": "l" } } ] }
Код ошибки:
FORM.HEADER_HORIZONTAL_SPACE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаheader
в строке. -
Правила формирования горизонтальных и вертикальных внутренних отступов подвала формы (элемента
footer
) должны быть аналогичны правилам отступов заголовка.Код ошибки:
FORM.FOOTER_VERTICAL_SPACE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаfooter
в строке.Код ошибки:
FORM.FOOTER_HORIZONTAL_SPACE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элементаfooter
в строке. -
Размер текстовых блоков в подвале должен соответствовать эталонному.
{ "block": "form", "content": [ { "block": "input", "mods": { "size": "l" } }, { "block": "form", "elem": "footer", "content": [ // правильно { "block": "text", "mods": { "size": "l" } }, // неправильно { "block": "text", "mods": { "size": "xxl" } } ] } ] }
Код ошибки:
FORM.FOOTER_TEXT_SIZE_IS_INVALID
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного блокаtext
в строке.
-
Заголовок первого уровня (блок
text
с модификатором typeh1
) должен быть один на странице.[ { "block": "text", "mods": { "type": "h1" } }, // неправильно { "block": "text", "mods": { "type": "h1" } } ]
Код ошибки:
TEXT.SEVERAL_H1
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного заголовка. -
Заголовок второго уровня (блок
text
с модификатором typeh2
) не может следовать перед заголовком первого уровня на одном или более глубоком уровне вложенности.[ // неправильно { "block": "text", "mods": { "type": "h2" } }, { "block": "text", "mods": { "type": "h1" } } ]
Код ошибки:
TEXT.INVALID_H2_POSITION
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного заголовка. -
Заголовок второго уровня (блок
text
с модификатором typeh3
) не может следовать перед заголовком второго уровня на одном или более глубоком уровне вложенности.[ // неправильно { "block": "text", "mods": { "type": "h3" } }, { "block": "text", "mods": { "type": "h2" } } ]
Код ошибки:
TEXT.INVALID_H3_POSITION
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного заголовка.
Мы будем оценивать корректную реализацию функциональности, а также:
- архитектуру приложения;
- организованную вами инфраструктуру для разработки;
- наличие и качество автотестов;
- performance;
- оформление кода и общую аккуратность работы.