shri-t2-egor
v1.0.1
Published
В этом репозитории находятся материалы тестового задания «Напишите линтер» для [16-й Школы разработки интерфейсов](https://yandex.ru/promo/academy/shri) (зима 2020, Москва).
Readme
Задание 2. Напишите линтер
В этом репозитории находятся материалы тестового задания «Напишите линтер» для 16-й Школы разработки интерфейсов (зима 2020, Москва).
Задание
Вам нужно написать линтер, проверяющий, что структура блоков интерфейса соответствует правилам. В качестве решения приложите исходный код и запускаемый файл линтера.
Запускаемый файл должен называться linter.js и находиться в репозитории в папке build. Размер файла — не более 1 МБ. Код файла должен создавать в глобальной области видимости функцию lint. Эта функция должна одинаково работать в браузере и Node.JS. Для работы линтера не должны требоваться внешние зависимости, находящиеся вне файла linter.js.
Мы не ограничиваем вас в выборе технологий, фреймворков и библиотек. Пожалуйста, для каждого выбранного инструмента напишите краткое обоснование: зачем он нужен в вашем проекте, и почему именно он.
Формат входных и выходных данных
Линтер получает на вход строку string, которая описывает структуру блоков интерфейса в формате JSON. Формат описания блоков такой же, как в первом задании. Например:
const json = `{
"block": "warning",
"content": [
{
"block": "placeholder",
"mods": { "size": "m" }
},
{
"elem": "content",
"content": [
{
"block": "text",
"mods": { "size": "m" }
},
{
"block": "text",
"mods": { "size": "l" }
}
]
}
]
}`;На выходе линтер должен выдавать массив ошибок. Каждый элемент массива должен описывать одну ошибку (нарушение правила), и у него должны быть поля:
error— текст ошибки; для каждого правила выберите текст ошибки на свое усмотрение;code— код ошибки; указан для каждого правила в его описании;location— информация о положении ошибочного блока в исходной строке. В полеlocationдолжны быть поляstartиend, каждое из которых содержит номер строки и символа в ней. Нумерация строк и символов начинается с 1.
Для указанного выше примера результат работы линтера будет таким:
[
{
"code": "WARNING.TEXT_SIZES_SHOULD_BE_EQUAL",
"error": "Тексты в блоке warning должны быть одного размера",
"location": {
"start": { "column": 1, "line": 1 },
"end": { "column": 2, "line": 22 }
}
}
]Если ошибок нет, линтер должен вернуть пустой массив.
Проверка автотестами
Чтобы уменьшить нагрузку на преподавателей, которые будут оценивать задания, мы хотим предварительно проверить решения автотестами. Если ваше решение не прошло автотесты, оно вернется на доработку и не дойдет до ручной проверки.
Для автотестов важна файловая структура вашего репозитория и формат входных и выходных данных. Пожалуйста, в точности выполните требования, указанные выше!
Style guide
Правила линтинга блока warning
Все тексты (блоки text) в блоке warning должны быть одного размера, то есть c одинаковым значением модификатора size, и этот размер должен быть определен. Размер первого из таких элементов в форме будем считать эталонным. Например:
{ "block": "warning", // правильно "content": [ { "block": "text", "mods": { "size": "l" } }, { "block": "text", "mods": { "size": "l" } } ] // неправильно "content": [ { "block": "text", "mods": { "size": "l" } }, { "block": "text", "mods": { "size": "m" } } ] }Код ошибки:
WARNING.TEXT_SIZES_SHOULD_BE_EQUAL
Позиция ошибки: в качестве позицийstartиendнеобходимо указать позицию первого и последнего символов ошибочного блокаwarningв строке.Размер кнопки блока
warningдолжен быть на 1 шаг больше эталонного (например, для размераlтаким значением будетxl).{ "block": "warning", "content": [ { "block": "text", "mods": { "size": "l" } }, // правильно { "block": "button", "mods": { "size": "xl" } } // неправильно { "block": "button", "mods": { "size": "s" } } ] }Код ошибки:
WARNING.INVALID_BUTTON_SIZE
Позиция ошибки: в качестве позицийstartиendнеобходимо указать позицию первого и последнего символов ошибочного блокаbuttonв строке.Блок
buttonв блокеwarningне может находиться перед блокомplaceholderна том же или более глубоком уровне вложенности.{ "block": "warning", "content": [ // правильно { "block": "placeholder", "mods": { size: "m" }, { "block": "button", "mods": { "size": "m" } } // неправильно { "block": "button", "mods": { "size": "m" } }, { "block": "placeholder", "mods": { size: "m" } ] }Код ошибки:
WARNING.INVALID_BUTTON_POSITION
Позиция ошибки: в качестве позицийstartиendнеобходимо указать позицию первого и последнего символов ошибочного блокаbuttonв строке.Допустимые размеры для блока
placeholderв блокеwarning(значение модификатораsize):s,m,l.{ "block": "warning", "content": [ // правильно { "block": "placeholder", "mods": { size: "m" } // неправильно { "block": "placeholder", "mods": { size: "xl" } ] }Код ошибки:
WARNING.INVALID_PLACEHOLDER_SIZE
Позиция ошибки: в качестве позицийstartиendнеобходимо указать позицию первого и последнего символов ошибочного блокаbuttonв строке.
Правила линтинга заголовков на странице
Заголовок первого уровня (блок
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необходимо указать позицию первого и последнего символов ошибочного заголовка.
Правила линтинга пропорции функциональных и рекламных блоков
Все контентные блоки в интерфейсе можно разделить на два типа:
Информационно-функциональные:
payment,warning,product,history,cover,collect,articles,subscribtion,event;Маркетинговые:
commercial,offer.
Нужно проверить, что маркетинговые блоки занимают не больше половины от всех колонок блока grid. Считается, что одну колонку может занимать только один из вышеописанных блоков.
{
"block": "grid",
"mods": {
"m-columns": "10"
},
// правильно
"content": [
{
"block": "grid",
"elem": "fraction",
"elemMods": {
"m-col": "8"
},
"content": [
{
"block": "payment"
}
]
},
{
"block": "grid",
"elem": "fraction",
"elemMods": {
"m-col": "2"
},
"content": [
{
"block": "offer"
}
]
}
]
// неправильно
"content": [
{
"block": "grid",
"elem": "fraction",
"elemMods": {
"m-col": "2"
},
"content": [
{
"block": "payment"
}
]
},
{
"block": "grid",
"elem": "fraction",
"elemMods": {
"m-col": "8"
},
"content": [
{
"block": "offer"
}
]
}
]
}Код ошибки: GRID.TOO_MUCH_MARKETING_BLOCKS
Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного блока grid.
Что мы проверяем этим заданием
Мы будем оценивать корректную реализацию функциональности, а также:
- архитектуру приложения,
- организованную вами инфраструктуру для разработки,
- качество автотестов,
- performance,
- оформление кода и аккуратность работы.
