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

visgl / loaders.gl / 24153816851

08 Apr 2026 07:17PM UTC coverage: 53.247% (-12.1%) from 65.319%
24153816851

push

github

web-flow
chore: Move from tape to vitest (#3351)

8651 of 17291 branches covered (50.03%)

Branch coverage included in aggregate %.

7 of 7 new or added lines in 1 file covered. (100.0%)

2031 existing lines in 296 files now uncovered.

17563 of 31940 relevant lines covered (54.99%)

5279.54 hits per line

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

72.3
/modules/loader-utils/src/lib/path-utils/path.ts
1
// Beginning of a minimal implementation of the Node.js path API, that doesn't pull in big polyfills.
2

3
import {getCWD} from './get-cwd';
4

5
/**
6
 * Replacement for Node.js path.filename
7
 * @param url
8
 */
9
export function filename(url: string): string {
10
  const slashIndex = url ? url.lastIndexOf('/') : -1;
80,868!
11
  return slashIndex >= 0 ? url.substr(slashIndex + 1) : url;
80,868✔
12
}
13

14
/**
15
 * Replacement for Node.js path.dirname
16
 * @param url
17
 */
18
export function dirname(url: string): string {
19
  const slashIndex = url ? url.lastIndexOf('/') : -1;
81,178✔
20
  return slashIndex >= 0 ? url.substr(0, slashIndex) : '';
81,178✔
21
}
22

23
/**
24
 * Replacement for Node.js path.join
25
 * @param parts
26
 */
27
export function join(...parts: string[]): string {
UNCOV
28
  const separator = '/';
×
UNCOV
29
  parts = parts.map((part, index) => {
×
UNCOV
30
    if (index) {
×
UNCOV
31
      part = part.replace(new RegExp(`^${separator}`), '');
×
32
    }
UNCOV
33
    if (index !== parts.length - 1) {
×
UNCOV
34
      part = part.replace(new RegExp(`${separator}$`), '');
×
35
    }
UNCOV
36
    return part;
×
37
  });
UNCOV
38
  return parts.join(separator);
×
39
}
40

41
/* eslint-disable no-continue */
42

43
/**
44
 * https://nodejs.org/api/path.html#path_path_resolve_paths
45
 * @param paths A sequence of paths or path segments.
46
 * @return resolved path
47
 * Forked from BTOdell/path-resolve under MIT license
48
 * @see https://github.com/BTOdell/path-resolve/blob/master/LICENSE
49
 */
50
export function resolve(...components: string[]): string {
51
  const paths: string[] = [];
297✔
52
  for (let _i = 0; _i < components.length; _i++) {
297✔
53
    paths[_i] = components[_i];
414✔
54
  }
55
  let resolvedPath = '';
297✔
56
  let resolvedAbsolute = false;
297✔
57
  let cwd: string | undefined;
58
  for (let i = paths.length - 1; i >= -1 && !resolvedAbsolute; i--) {
297✔
59
    let path: string | undefined;
60
    if (i >= 0) {
594✔
61
      path = paths[i];
414✔
62
    } else {
63
      if (cwd === undefined) {
180!
64
        cwd = getCWD();
180✔
65
      }
66
      path = cwd;
180✔
67
    }
68
    // Skip empty entries
69
    if (path.length === 0) {
594!
70
      continue;
×
71
    }
72
    resolvedPath = `${path}/${resolvedPath}`;
594✔
73
    resolvedAbsolute = path.charCodeAt(0) === SLASH;
594✔
74
  }
75
  // At this point the path should be resolved to a full absolute path, but
76
  // handle relative paths to be safe (might happen when process.cwd() fails)
77
  // Normalize the path (removes leading slash)
78
  resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
297✔
79
  if (resolvedAbsolute) {
297!
80
    return `/${resolvedPath}`;
297✔
UNCOV
81
  } else if (resolvedPath.length > 0) {
×
UNCOV
82
    return resolvedPath;
×
83
  }
UNCOV
84
  return '.';
×
85
}
86

87
const SLASH = 47;
348✔
88
const DOT = 46;
348✔
89

90
/**
91
 * Resolves . and .. elements in a path with directory names
92
 * Forked from BTOdell/path-resolve under MIT license
93
 * @see https://github.com/BTOdell/path-resolve/blob/master/LICENSE
94
 */
95
/* eslint-disable max-depth */
96
// eslint-disable-next-line complexity, max-statements
97
function normalizeStringPosix(path: string, allowAboveRoot: boolean): string {
98
  let res = '';
297✔
99
  let lastSlash = -1;
297✔
100
  let dots = 0;
297✔
101
  let code: number | undefined;
102
  let isAboveRoot = false;
297✔
103

104
  for (let i = 0; i <= path.length; ++i) {
297✔
105
    if (i < path.length) {
21,021✔
106
      code = path.charCodeAt(i);
20,724✔
107
    } else if (code === SLASH) {
297!
108
      break;
297✔
109
    } else {
110
      code = SLASH;
×
111
    }
112
    if (code === SLASH) {
20,724✔
113
      if (lastSlash === i - 1 || dots === 1) {
2,985✔
114
        // NOOP
115
      } else if (lastSlash !== i - 1 && dots === 2) {
5,016✔
116
        if (
84!
117
          res.length < 2 ||
144!
118
          !isAboveRoot ||
119
          res.charCodeAt(res.length - 1) !== DOT ||
120
          res.charCodeAt(res.length - 2) !== DOT
121
        ) {
122
          if (res.length > 2) {
84✔
123
            const start = res.length - 1;
60✔
124
            let j = start;
60✔
125
            for (; j >= 0; --j) {
60✔
126
              if (res.charCodeAt(j) === SLASH) {
1,002✔
127
                break;
47✔
128
              }
129
            }
130
            if (j !== start) {
60!
131
              res = j === -1 ? '' : res.slice(0, j);
60✔
132
              lastSlash = i;
60✔
133
              dots = 0;
60✔
134
              isAboveRoot = false;
60✔
135
              continue;
60✔
136
            }
137
          } else if (res.length === 2 || res.length === 1) {
24!
138
            res = '';
×
139
            lastSlash = i;
×
140
            dots = 0;
×
141
            isAboveRoot = false;
×
142
            continue;
×
143
          }
144
        }
145
        if (allowAboveRoot) {
24!
146
          if (res.length > 0) {
×
147
            res += '/..';
×
148
          } else {
149
            res = '..';
×
150
          }
151
          isAboveRoot = true;
×
152
        }
153
      } else {
154
        const slice = path.slice(lastSlash + 1, i);
2,424✔
155
        if (res.length > 0) {
2,424✔
156
          res += `/${slice}`;
2,114✔
157
        } else {
158
          res = slice;
310✔
159
        }
160
        isAboveRoot = false;
2,424✔
161
      }
162
      lastSlash = i;
2,925✔
163
      dots = 0;
2,925✔
164
    } else if (code === DOT && dots !== -1) {
17,739✔
165
      ++dots;
348✔
166
    } else {
167
      dots = -1;
17,391✔
168
    }
169
  }
170
  return res;
297✔
171
}
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