Gwinbleind / task-2

Задание 2. Напишите линтер — ШРИ, Москва, осень 2019

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Задание 2. Напишите линтер

В этом репозитории находятся материалы тестового задания «Напишите линтер» для 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": { "column": 1, "line": 1 },
            "end": { "column": 2, "line": 17 }
        }
    }
]

Если ошибок нет, линтер должен вернуть пустой массив.

Проверка автотестами

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

Для автотестов важна файловая структура вашего репозитория и формат входных/выходных данных. Пожалуйста в точности выполните требования, указанные выше!

Style guide

Правила линтинга блока form

  1. Все инпуты, кнопки и тексты в лейблах в блоке формы должны быть одного размера (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 в строке.

  2. Вертикальный внутренний отступ контентного элемента формы 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 в строке.

  3. Горизонтальный внутренний отступ контентного элемента должен задаваться с помощью модификатора 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 в строке.

  4. Строки формы (в которые складываются лейбл и инпут) помечаются элементом формы 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" } }],
                    "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 в строке.

  5. Все текстовые блоки в заголовке формы (элемент 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 в строке.

  6. Вертикальный внутренний отступ заголовка формы должен быть задан с помощью микса на него элемента формы 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 в строке.

  7. Горизонтальный внутренний отступ должен быть на 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 в строке.

  8. Правила формирования горизонтальных и вертикальных внутренних отступов подвала формы (элемента footer) должны быть аналогичны правилам отступов заголовка.

    Код ошибки: FORM.FOOTER_VERTICAL_SPACE_IS_INVALID
    Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элемента footer в строке.

    Код ошибки: FORM.FOOTER_HORIZONTAL_SPACE_IS_INVALID
    Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного элемента footer в строке.

  9. Размер текстовых блоков в подвале должен соответствовать эталонному.

    {
        "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 в строке.

Правила линтинга заголовков на странице

  1. Заголовок первого уровня (блок text с модификатором type h1) должен быть один на странице.

    [
        {
            "block": "text",
            "mods": { "type": "h1" }
        },
    
        // неправильно
        {
            "block": "text",
            "mods": { "type": "h1" }
        }
    ]

    Код ошибки: TEXT.SEVERAL_H1
    Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного заголовка.

  2. Заголовок второго уровня (блок text с модификатором type h2) не может следовать перед заголовком первого уровня на одном или более глубоком уровне вложенности.

    [
        // неправильно
        {
            "block": "text",
            "mods": { "type": "h2" }
        },
        {
            "block": "text",
            "mods": { "type": "h1" }
        }
    ]

    Код ошибки: TEXT.INVALID_H2_POSITION
    Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного заголовка.

  3. Заголовок третьего уровня (блок text с модификатором type h3) не может следовать перед заголовком второго уровня на одном или более глубоком уровне вложенности.

    [
        // неправильно
        {
            "block": "text",
            "mods": { "type": "h3" }
        },
        {
            "block": "text",
            "mods": { "type": "h2" }
        }
    ]

    Код ошибки: TEXT.INVALID_H3_POSITION
    Позиция ошибки: в качестве позиций start и end необходимо указать позицию первого и последнего символов ошибочного заголовка.

Что мы проверяем этим заданием

Мы будем оценивать корректную реализацию функциональности, а также:

  • архитектуру приложения;
  • организованную вами инфраструктуру для разработки;
  • наличие и качество автотестов;
  • performance;
  • оформление кода и общую аккуратность работы.

About

Задание 2. Напишите линтер — ШРИ, Москва, осень 2019