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

pmcelhaney / counterfact / 6030589989

30 Aug 2023 10:12PM UTC coverage: 83.297% (-0.3%) from 83.567%
6030589989

push

github

web-flow
Merge pull request #540 from pmcelhaney/ci-fixes

390 of 424 branches covered (0.0%)

Branch coverage included in aggregate %.

1924 of 2354 relevant lines covered (81.73%)

9.6 hits per line

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

89.2
/src/typescript-generator/script.js
1
import nodePath from "node:path";
1✔
2

1✔
3
import createDebugger from "debug";
1✔
4
import prettier from "prettier";
1✔
5

1✔
6
const debug = createDebugger("counterfact:typescript-generator:script");
1✔
7

1✔
8
export class Script {
1✔
9
  constructor(repository, path) {
1✔
10
    this.repository = repository;
16✔
11
    this.exports = new Map();
16✔
12
    this.imports = new Map();
16✔
13
    this.externalImports = new Map();
16✔
14
    this.cache = new Map();
16✔
15
    this.typeCache = new Map();
16✔
16
    this.path = path;
16✔
17
  }
16✔
18

1✔
19
  firstUniqueName(coder) {
1✔
20
    for (const name of coder.names()) {
29✔
21
      if (!this.imports.has(name) && !this.exports.has(name)) {
50✔
22
        return name;
29✔
23
      }
29✔
24
    }
50✔
25

×
26
    throw new Error(`could not find a unique name for ${coder.id}`);
×
27
  }
×
28

1✔
29
  export(coder, isType = false, isDefault = false) {
1✔
30
    const cacheKey = isDefault
18✔
31
      ? "default"
15✔
32
      : `${coder.id}@${nodePath}:${isType}`;
15✔
33

18✔
34
    if (this.cache.has(cacheKey)) {
18!
35
      return this.cache.get(cacheKey);
×
36
    }
×
37

18✔
38
    const name = this.firstUniqueName(coder);
18✔
39

18✔
40
    this.cache.set(cacheKey, name);
18✔
41

18✔
42
    const exportStatement = {
18✔
43
      beforeExport: coder.beforeExport(this.path),
18✔
44
      done: false,
18✔
45
      id: coder.id,
18✔
46
      isDefault,
18✔
47
      isType,
18✔
48
      typeDeclaration: coder.typeDeclaration(this.exports, this),
18✔
49
    };
18✔
50

18✔
51
    exportStatement.promise = coder
18✔
52
      .delegate()
18✔
53
      // eslint-disable-next-line promise/prefer-await-to-then
18✔
54
      .then((availableCoder) => {
18✔
55
        exportStatement.name = name;
18✔
56
        exportStatement.code = availableCoder.write(this);
18✔
57

18✔
58
        return availableCoder;
18✔
59
      })
18✔
60
      // eslint-disable-next-line promise/prefer-await-to-then
18✔
61
      .catch((error) => {
18✔
62
        exportStatement.code = `{/* error creating export "${name}" for ${this.path}: ${error.stack} */}`;
×
63
        exportStatement.error = error;
×
64
      })
×
65
      // eslint-disable-next-line promise/prefer-await-to-then
18✔
66
      .finally(() => {
18✔
67
        exportStatement.done = true;
18✔
68
      });
18✔
69

18✔
70
    this.exports.set(name, exportStatement);
18✔
71

18✔
72
    return name;
18✔
73
  }
18✔
74

1✔
75
  exportDefault(coder, isType = false) {
1✔
76
    this.export(coder, isType, true);
1✔
77
  }
1✔
78

1✔
79
  // eslint-disable-next-line max-statements
1✔
80
  import(coder, isType = false, isDefault = false) {
1✔
81
    debug("import coder: %s", coder.id);
13✔
82

13✔
83
    const modulePath = coder.modulePath();
13✔
84

13✔
85
    const cacheKey = `${coder.id}@${modulePath}:${isType}:${isDefault}`;
13✔
86

13✔
87
    debug("cache key: %s", cacheKey);
13✔
88

13✔
89
    if (this.cache.has(cacheKey)) {
13✔
90
      debug("cache hit: %s", cacheKey);
2✔
91

2✔
92
      return this.cache.get(cacheKey);
2✔
93
    }
2✔
94

11✔
95
    debug("cache miss: %s", cacheKey);
11✔
96

11✔
97
    const name = this.firstUniqueName(coder);
11✔
98

11✔
99
    this.cache.set(cacheKey, name);
11✔
100

11✔
101
    const scriptFromWhichToExport = this.repository.get(modulePath);
11✔
102

11✔
103
    const exportedName = scriptFromWhichToExport.export(
11✔
104
      coder,
11✔
105
      isType,
11✔
106
      isDefault,
11✔
107
    );
11✔
108

11✔
109
    this.imports.set(name, {
11✔
110
      isDefault,
11✔
111
      isType,
11✔
112
      name: exportedName,
11✔
113
      script: scriptFromWhichToExport,
11✔
114
    });
11✔
115

11✔
116
    return name;
11✔
117
  }
11✔
118

1✔
119
  importType(coder) {
1✔
120
    return this.import(coder, true);
2✔
121
  }
2✔
122

1✔
123
  importDefault(coder, isType = false) {
1✔
124
    return this.import(coder, isType, true);
2✔
125
  }
2✔
126

1✔
127
  importExternal(name, modulePath, isType = false) {
1✔
128
    this.externalImports.set(name, { isType, modulePath });
×
129

×
130
    return name;
×
131
  }
×
132

1✔
133
  importExternalType(name, modulePath) {
1✔
134
    return this.importExternal(name, modulePath, true);
×
135
  }
×
136

1✔
137
  exportType(coder) {
1✔
138
    return this.export(coder, true);
1✔
139
  }
1✔
140

1✔
141
  isInProgress() {
1✔
142
    return Array.from(this.exports.values()).some(
×
143
      (exportStatement) => !exportStatement.done,
×
144
    );
×
145
  }
×
146

1✔
147
  finished() {
1✔
148
    return Promise.all(
2✔
149
      Array.from(this.exports.values(), (value) => value.promise),
2✔
150
    );
2✔
151
  }
2✔
152

1✔
153
  externalImportsStatements() {
1✔
154
    return Array.from(
3✔
155
      this.externalImports,
3✔
156
      ([name, { isDefault, isType, modulePath }]) =>
3✔
157
        `import${isType ? " type" : ""} ${
×
158
          isDefault ? name : `{ ${name} }`
×
159
        } from "${modulePath}";`,
×
160
    );
3✔
161
  }
3✔
162

1✔
163
  importStatements() {
1✔
164
    return Array.from(this.imports, ([name, { isDefault, isType, script }]) => {
4✔
165
      const resolvedPath = nodePath
6✔
166
        .relative(
6✔
167
          nodePath.dirname(this.path).replaceAll("\\", "/"),
6✔
168
          script.path.replace(/\.ts$/u, ".js"),
6✔
169
        )
6✔
170
        .replaceAll("\\", "/");
6✔
171

6✔
172
      return `import${isType ? " type" : ""} ${
6✔
173
        isDefault ? name : `{ ${name} }`
6✔
174
      } from "${resolvedPath.includes("../") ? "" : "./"}${resolvedPath}";`;
6✔
175
    });
6✔
176
  }
4✔
177

1✔
178
  exportStatements() {
1✔
179
    return Array.from(
3✔
180
      this.exports.values(),
3✔
181
      ({ beforeExport, code, isDefault, isType, name, typeDeclaration }) => {
3✔
182
        if (code.raw) {
7!
183
          return code.raw;
×
184
        }
×
185

7✔
186
        if (isDefault) {
7✔
187
          return `${beforeExport}export default ${code};`;
1✔
188
        }
1✔
189

6✔
190
        const keyword = isType ? "type" : "const";
7✔
191
        const typeAnnotation =
7✔
192
          typeDeclaration.length === 0 ? "" : `:${typeDeclaration}`;
7!
193

7✔
194
        return `${beforeExport}export ${keyword} ${name}${typeAnnotation} = ${code};`;
7✔
195
      },
7✔
196
    );
3✔
197
  }
3✔
198

1✔
199
  contents() {
1✔
200
    return prettier.format(
3✔
201
      [
3✔
202
        this.externalImportsStatements().join("\n"),
3✔
203
        this.importStatements().join("\n"),
3✔
204
        "\n\n",
3✔
205
        this.exportStatements().join("\n\n"),
3✔
206
      ].join(""),
3✔
207
      { parser: "typescript" },
3✔
208
    );
3✔
209
  }
3✔
210
}
1✔
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