• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / js-slang / 24713997105

21 Apr 2026 09:09AM UTC coverage: 78.523% (+0.1%) from 78.391%
24713997105

Pull #1893

github

web-flow
Merge 6359230cf into 1402017f8
Pull Request #1893: Error Handling and Stringify Changes

3115 of 4184 branches covered (74.45%)

Branch coverage included in aggregate %.

793 of 967 new or added lines in 76 files covered. (82.01%)

20 existing lines in 11 files now uncovered.

7049 of 8760 relevant lines covered (80.47%)

173719.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.67
/src/stepper/nodes/Expression/ConditionalExpression.ts
1
import type { Comment, ConditionalExpression, SourceLocation } from 'estree';
2
import type { StepperExpression, StepperPattern } from '..';
3
import { convert } from '../../generator';
4
import { StepperBaseNode } from '../../interface';
5
import { checkIfStatement } from '../../../utils/rttc';
6
import type { RedexInfo } from '../..';
7
import { InternalRuntimeError } from '../../../errors/base';
8

9
export class StepperConditionalExpression
10
  extends StepperBaseNode<ConditionalExpression>
11
  implements ConditionalExpression
12
{
13
  constructor(
14
    public readonly test: StepperExpression,
1,847✔
15
    public readonly consequent: StepperExpression,
1,847✔
16
    public readonly alternate: StepperExpression,
1,847✔
17
    leadingComments?: Comment[],
18
    trailingComments?: Comment[],
19
    loc?: SourceLocation | null,
20
    range?: [number, number],
21
  ) {
22
    super('ConditionalExpression', leadingComments, trailingComments, loc, range);
1,847✔
23
  }
24

25
  static create(node: ConditionalExpression) {
26
    return new StepperConditionalExpression(
382✔
27
      convert(node.test),
28
      convert(node.consequent),
29
      convert(node.alternate),
30
      node.leadingComments,
31
      node.trailingComments,
32
      node.loc,
33
      node.range,
34
    );
35
  }
36

37
  public override isContractible(redex: RedexInfo): boolean {
38
    if (this.test.type !== 'Literal') return false;
2,487✔
39
    const test_value = this.test.value;
1,206✔
40
    checkIfStatement(this, test_value);
1,206✔
41

42
    redex.preRedex = [this];
1,206✔
43
    return true;
1,206✔
44
  }
45

46
  public override isOneStepPossible(redex: RedexInfo): boolean {
47
    return this.isContractible(redex) || this.test.isOneStepPossible(redex);
1,916✔
48
  }
49

50
  public override contract(redex: RedexInfo): StepperExpression {
51
    redex.preRedex = [this];
279✔
52
    if (this.test.type !== 'Literal' || typeof this.test.value !== 'boolean') {
279!
NEW
53
      throw new InternalRuntimeError(
×
54
        'Cannot contract ConditionalExpression with non-boolean literal test',
55
        this,
56
      );
57
    }
58

59
    const result = this.test.value ? this.consequent : this.alternate;
279✔
60
    redex.postRedex = [result];
279✔
61
    return result;
279✔
62
  }
63

64
  public override oneStep(redex: RedexInfo): StepperExpression {
65
    if (this.isContractible(redex)) {
571✔
66
      return this.contract(redex);
279✔
67
    }
68

69
    return new StepperConditionalExpression(
292✔
70
      this.test.oneStep(redex),
71
      this.consequent,
72
      this.alternate,
73
      this.leadingComments,
74
      this.trailingComments,
75
      this.loc,
76
      this.range,
77
    );
78
  }
79

80
  public override substitute(
81
    id: StepperPattern,
82
    value: StepperExpression,
83
    redex: RedexInfo,
84
  ): StepperExpression {
85
    return new StepperConditionalExpression(
1,173✔
86
      this.test.substitute(id, value, redex),
87
      this.consequent.substitute(id, value, redex),
88
      this.alternate.substitute(id, value, redex),
89
      this.leadingComments,
90
      this.trailingComments,
91
      this.loc,
92
      this.range,
93
    );
94
  }
95

96
  public override freeNames(): string[] {
97
    return Array.from(
144✔
98
      new Set([
99
        ...this.test.freeNames(),
100
        ...this.consequent.freeNames(),
101
        ...this.alternate.freeNames(),
102
      ]),
103
    );
104
  }
105

106
  public override allNames(): string[] {
107
    return Array.from(
574✔
108
      new Set([
109
        ...this.test.allNames(),
110
        ...this.consequent.allNames(),
111
        ...this.alternate.allNames(),
112
      ]),
113
    );
114
  }
115

116
  public override rename(before: string, after: string): StepperExpression {
117
    return new StepperConditionalExpression(
×
118
      this.test.rename(before, after),
119
      this.consequent.rename(before, after),
120
      this.alternate.rename(before, after),
121
      this.leadingComments,
122
      this.trailingComments,
123
      this.loc,
124
      this.range,
125
    );
126
  }
127
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc