Строка определения класса отображается как непокрытая ветвь, кто-нибудь может определить, почему?

#typescript #class #jestjs #code-coverage #istanbul

Вопрос:

Я пытаюсь получить 100% покрытие для своего API «Lauf Store» ( https://cefn.com/lauf/api/ )

Строка определения класса ниже-единственная строка в проекте, в которой не охвачены все логические ветви. Однако я не вижу, как у него вообще есть какие-либо логические ветви.

 class DefaultStore<State extends RootState> extends DefaultWatchableState<Immutable<State>> implements Store<State> {
 

Я исследовал конструктор, унаследованный от суперкласса (DefaultWatchableState), чтобы выяснить, могут ли его вызовы отличаться каким-либо образом, который не был протестирован, и написал тесты как с необязательным параметром конструктора, так и без него, но это не решило проблему.

Теперь я застрял, пытаясь понять, каким образом линия может иметь более одной ветви.

Отчет о тестовом покрытии выглядит следующим образом, показывая строку 7 (вставленную выше) как виновника с какой-то непроверенной ветвью…

 --------------------|---------|----------|---------|---------|-------------------
File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
--------------------|---------|----------|---------|---------|-------------------
All files           |     100 |    90.91 |     100 |     100 |                   
 src                |     100 |      100 |     100 |     100 |                   
  index.ts          |     100 |      100 |     100 |     100 |                   
 src/core           |     100 |    90.91 |     100 |     100 |                   
  index.ts          |     100 |      100 |     100 |     100 |                   
  partition.ts      |     100 |      100 |     100 |     100 |                   
  store.ts          |     100 |    66.67 |     100 |     100 | 7                 
  watchable.ts      |     100 |      100 |     100 |     100 |                   
  watchableState.ts |     100 |      100 |     100 |     100 |                   
 src/types          |     100 |      100 |     100 |     100 |                   
  index.ts          |     100 |      100 |     100 |     100 |                   
 test               |     100 |      100 |     100 |     100 |                   
  util.ts           |     100 |      100 |     100 |     100 |                   
 test/core          |     100 |      100 |     100 |     100 |                   
  storeSuite.ts     |     100 |      100 |     100 |     100 |                   
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 3 passed, 3 total
Tests:       27 passed, 27 total
Snapshots:   0 total
Time:        7.629 s
Ran all test suites.
Done in 8.82s.
 

Вот он в контексте его полного исходного файла…

 import { castDraft, produce } from "immer";
import type { RootState, Selector, Store, Watcher } from "../types";
import type { Editor, Immutable } from "../types/immutable";
import { DefaultWatchableState } from "./watchableState";

/** Reference implementation of Lauf [[Store]]  */
class DefaultStore<State extends RootState>
  extends DefaultWatchableState<Immutable<State>>
  implements Store<State> {
  edit = (editor: Editor<State>) => {
    const nextState = (produce<Immutable<State>>(this.read(), (draft) =>
      editor(draft, castDraft)
    ) as unknown) as Immutable<State>;
    return this.write(nextState);
  };

  select = <Selected>(selector: Selector<State, Selected>) => {
    return selector(this.read());
  };
}

/** Initialise a [[Store]] with an [[Immutable]] initial [[RootState]] - any
 * array, tuple or object. This state can be updated and monitored for updates
 * to drive an app.
 * @param initialState - The initial [[RootState]] stored
 * @param watchers - A list of [[Watcher|Watchers]] to be notified once and permanently subscribed 
 * @category
 */
export function createStore<State extends RootState>(
  initialState: Immutable<State>,
  watchers?: ReadonlyArray<Watcher<State>>
): Store<State> {
  return new DefaultStore(initialState, watchers);
}

 

…and you can see it in the context of its full code at https://github.com/cefn/lauf/blob/0cf3c153b289a70097de0e8c1e10ff45c02305a8/modules/lauf-store/src/core/store.ts#L7

Can anyone see how this line can have more than one code branch and what I need to do to visit that code branch in my tests?

It looks like a single class declaration line with no branches to me, and the class is used everywhere so the use of the definition definitely has coverage.

PS If you have a Docker image with git and yarn (or a similar environment where you are happy to run untrusted code) it’s possible to recreate the error in about 30 seconds like git clone https://github.com/cefn/lauf.git amp;amp; cd lauf amp;amp; git checkout 0cf3c15 amp;amp; yarn amp;amp; cd modules/lauf-store amp;amp; yarn run test if you want to experiment.