Утверждение ошибки типа потока в модульных тестах

Мы используем Flow для статической проверки типов в JavaScript. Типы потока могут быть сложными, и у нас были проблемы, когда мы думали, что у нас есть хорошая защита статического типа от уродливых объектов, но проблемы аннотации потока означали, что проверка типов на самом деле не улавливала проблемы.

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

type User = {|
    name: string
|};

const user = {name: "Bob"};
(user: User);

Это пройдет, если user является действительным Userи провалить проверку типа, если это не так.

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

const user = {name: "Bob", age: 40};

Я могу пройти тест с

// $ExpectError
const user = {name: "Bob", age: 40};

но я не могу заставить его потерпеть неудачу с

// $ExpectError
const user = {name: "Bob"};

Очевидно, этот пример довольно тривиален, но более сложные типы (например, с обобщениями) могут выиграть от этого типа тестирования.

Варианты, которые я рассмотрел:

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

Есть ли способ статически утверждать, что утверждение потока должно потерпеть неудачу, и выдать ошибку, если это не так?

1 ответ

Решение

Чтобы утверждать, что определенные строки кода в ваших модульных тестах должны вызывать ошибки потока, просто напишите комментарий подавления ошибок потока над этими строками, а затем выполните команду flow check --max-warnings 0 на всю вашу папку модульных тестов (или всю вашу кодовую базу) и утверждайте, что команда имеет статус 0 выхода (без ошибок или предупреждений). Вам не нужно запускать команды для каждого файла модульного теста в отдельности.

В качестве документации дляsuppress_comment говорит, что Flow выдаст предупреждение, если вы напишите комментарий подавления, такой как // $FlowExpectError выше линии, которая фактически не вызывает ошибку потока.

Предполагая, что вы определили suppress_comment чтобы понять $FlowExpectError в качестве комментария подавления, вот как будут выглядеть ваши юнит-тесты:

// this type definition could be imported from another file
type User = {|
    name: string
|};

// Check that Flow doesn’t raise an error for correct usages
const user = {name: "Bob"};

// Check that Flow does raise an error for incorrect usages
// $FlowExpectError
const user = {name: "Bob", age: 40};

Если вы бежите flow check --max-warnings 0 в папке, содержащей этот файл и команда завершается успешно, то ваши тесты для вашего User Тип пройден.

Другие вопросы по тегам