@aplaytest/impact 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -0
- package/dist/coverage.d.ts +57 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +118 -0
- package/dist/coverage.js.map +1 -0
- package/dist/graph.d.ts +79 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +144 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/select.d.ts +77 -0
- package/dist/select.d.ts.map +1 -0
- package/dist/select.js +204 -0
- package/dist/select.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/typescript/lib/lib.es2023.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/@ts-morph/common/lib/typescript.d.ts","../../../node_modules/@ts-morph/common/lib/ts-morph-common.d.ts","../../../node_modules/ts-morph/lib/ts-morph.d.ts","../src/coverage.ts","../src/graph.ts","../src/select.ts","../src/index.ts","../../../node_modules/@types/deep-eql/index.d.ts","../../../node_modules/assertion-error/index.d.ts","../../../node_modules/@types/chai/index.d.ts","../../../node_modules/@types/node/compatibility/disposable.d.ts","../../../node_modules/@types/node/compatibility/indexable.d.ts","../../../node_modules/@types/node/compatibility/iterators.d.ts","../../../node_modules/@types/node/compatibility/index.d.ts","../../../node_modules/@types/node/globals.typedarray.d.ts","../../../node_modules/@types/node/buffer.buffer.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../node_modules/@types/node/web-globals/domexception.d.ts","../../../node_modules/@types/node/web-globals/events.d.ts","../../../node_modules/buffer/index.d.ts","../../../node_modules/undici-types/header.d.ts","../../../node_modules/undici-types/readable.d.ts","../../../node_modules/undici-types/file.d.ts","../../../node_modules/undici-types/fetch.d.ts","../../../node_modules/undici-types/formdata.d.ts","../../../node_modules/undici-types/connector.d.ts","../../../node_modules/undici-types/client.d.ts","../../../node_modules/undici-types/errors.d.ts","../../../node_modules/undici-types/dispatcher.d.ts","../../../node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/undici-types/global-origin.d.ts","../../../node_modules/undici-types/pool-stats.d.ts","../../../node_modules/undici-types/pool.d.ts","../../../node_modules/undici-types/handlers.d.ts","../../../node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/undici-types/agent.d.ts","../../../node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/undici-types/mock-agent.d.ts","../../../node_modules/undici-types/mock-client.d.ts","../../../node_modules/undici-types/mock-pool.d.ts","../../../node_modules/undici-types/mock-errors.d.ts","../../../node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/undici-types/retry-handler.d.ts","../../../node_modules/undici-types/retry-agent.d.ts","../../../node_modules/undici-types/api.d.ts","../../../node_modules/undici-types/interceptors.d.ts","../../../node_modules/undici-types/util.d.ts","../../../node_modules/undici-types/cookies.d.ts","../../../node_modules/undici-types/patch.d.ts","../../../node_modules/undici-types/websocket.d.ts","../../../node_modules/undici-types/eventsource.d.ts","../../../node_modules/undici-types/filereader.d.ts","../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/undici-types/content-type.d.ts","../../../node_modules/undici-types/cache.d.ts","../../../node_modules/undici-types/index.d.ts","../../../node_modules/@types/node/web-globals/fetch.d.ts","../../../node_modules/@types/node/web-globals/navigator.d.ts","../../../node_modules/@types/node/web-globals/storage.d.ts","../../../node_modules/@types/node/web-globals/streams.d.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/inspector.generated.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/sea.d.ts","../../../node_modules/@types/node/sqlite.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/index.d.ts","../../../node_modules/@types/ssh2/index.d.ts","../../../node_modules/@types/docker-modem/index.d.ts","../../../node_modules/@types/dockerode/index.d.ts","../../../node_modules/@types/estree/index.d.ts","../../../node_modules/@types/ssh2-streams/index.d.ts"],"fileIdsList":[[62,77,127,144,145],[77,127,144,145],[69,70,77,127,144,145],[77,127,141,144,145,147,159,177,178],[77,127,138,144,145,159,177,178,179],[77,124,125,127,144,145],[77,126,127,144,145],[127,144,145],[77,127,132,144,145,162],[77,127,128,133,138,144,145,147,159,170],[77,127,128,129,138,144,145,147],[72,73,74,77,127,144,145],[77,127,130,144,145,171],[77,127,131,132,139,144,145,148],[77,127,132,144,145,159,167],[77,127,133,135,138,144,145,147],[77,126,127,134,144,145],[77,127,135,136,144,145],[77,127,137,138,144,145],[77,126,127,138,144,145],[77,127,138,139,140,144,145,159,170],[77,127,138,139,140,144,145,154,159,162],[77,119,127,135,138,141,144,145,147,159,170],[77,127,138,139,141,142,144,145,147,159,167,170],[77,127,141,143,144,145,159,167,170],[75,76,77,78,79,80,81,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176],[77,127,138,144,145],[77,127,144,145,146,170],[77,127,135,138,144,145,147,159],[77,127,144,145,148],[77,127,144,145,149],[77,126,127,144,145,150],[77,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176],[77,127,144,145,152],[77,127,144,145,153],[77,127,138,144,145,154,155],[77,127,144,145,154,156,171,173],[77,127,139,144,145],[77,127,138,144,145,159,160,162],[77,127,144,145,161,162],[77,127,144,145,159,160],[77,127,144,145,162],[77,127,144,145,163],[77,124,127,144,145,159,164,170],[77,127,138,144,145,165,166],[77,127,144,145,165,166],[77,127,132,144,145,147,159,167],[77,127,144,145,168],[77,127,144,145,147,169],[77,127,141,144,145,153,170],[77,127,132,144,145,171],[77,127,144,145,159,172],[77,127,144,145,146,173],[77,127,144,145,174],[77,119,127,144,145],[77,119,127,138,140,144,145,150,159,162,170,172,173,175],[77,127,144,145,159,176],[77,127,144,145,159,177],[77,127,138,141,143,144,145,147,159,177],[63,77,127,144,145],[77,91,95,127,144,145,170],[77,91,127,144,145,159,170],[77,86,127,144,145],[77,88,91,127,144,145,167,170],[77,127,144,145,147,167],[77,127,144,145,177],[77,86,127,144,145,177],[77,88,91,127,144,145,147,170],[77,83,84,87,90,127,138,144,145,159,170],[77,91,98,127,144,145],[77,83,89,127,144,145],[77,91,112,113,127,144,145],[77,87,91,127,144,145,162,170,177],[77,112,127,144,145,177],[77,85,86,127,144,145,177],[77,91,127,144,145],[77,85,86,87,88,89,90,91,92,93,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,113,114,115,116,117,118,127,144,145],[77,91,106,127,144,145],[77,91,98,99,127,144,145],[77,89,91,99,100,127,144,145],[77,90,127,144,145],[77,83,86,91,127,144,145],[77,91,95,99,100,127,144,145],[77,95,127,144,145],[77,89,91,94,127,144,145,170],[77,83,88,91,98,127,144,145],[77,127,144,145,159],[77,86,91,112,127,144,145,175,177],[64,77,127,144,145,149],[65,66,67,77,127,144,145],[65,66,77,127,144,145]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"5a8bd1be1e99d9c8ff506ecdb984031b550784676e8fb6dfd616007aafd903cc","impliedFormat":1},{"version":"865d1a23e14b20e0cb02dbe0827797b0f0e8c5bd4568dcec24a12afef00d33d6","impliedFormat":1},{"version":"f5845a852a03600100175392ca764626cff5782f4d00d24300d82b8edaddeab9","impliedFormat":1},{"version":"09a6b23294792665fa9003e2341c875b2c8cbe3780815cbc41c0b61656b67b7c","signature":"1501edef689f32b9ab954c9e67f7bbfe5de43dc6e96e9ac5d2124d738deee4d3","impliedFormat":99},{"version":"46c18428df4007e815e618a5d351dd524300e685a46d79710cb12787b523c795","signature":"c4982be6010d5f63582b325999a75581386617918cc746344f171f5e21981cd3","impliedFormat":99},{"version":"e1a2423fb98778875350051776dac7674a2485a421450792c2f54bd438af8f72","signature":"c9efcea091f1f98bd3fb0dafe92a1c845ae7d09fdf53be68d3571b4f9975dfb1","impliedFormat":99},{"version":"dcf55ba61fb127c17c4e660110c90724daf70d9821532667bdac3dd99f8356e8","signature":"8f8f58f505dd9fe6593b08a5e3db93f0c4d58444cb09998b4ceed1237416aa08","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"4967529644e391115ca5592184d4b63980569adf60ee685f968fd59ab1557188","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"78dbea00e90d2df8ea3dbef0cc379d95b8be9b71cd6bde4c28728f306811803b","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e1e46d0a9837ee058c100501080c920fa98081ea3956af0374308ba6f22a33e","impliedFormat":1},{"version":"272ca407e0c9068bdc5152552d876e68037ceae3de62e529306403e973dec8e1","impliedFormat":1},{"version":"fa7834c715d5357e4540cee40ce96c3250ddb67a7b879a6b7fa0e86d6696f121","impliedFormat":1},{"version":"22dfb07a7ab15b66ac043829056fe70124844636ae719551812ac631ba04985b","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"0cb167c371eaa8c869f8a7656a7296f2e4fae43b4d8b803a680236b24794e5f9","impliedFormat":1},{"version":"0a839dba0287cc0481ad4beedd48a1c64acf1e212ae865d1315f7007ca215161","impliedFormat":1},{"version":"38dc4655376cd1a4bd6bb3763d92949233e33d38d3dd3cbea7bbf218175a38ef","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"d61e0a64cd175208ac0b83670151a9a6b5916f0d1ffcdc5c29c90b1cebfc5045","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"48a679952eefe4cb776d5a0e1ccba2d3eb53b57448bbb7abc1fcebcbd5440188","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2d14da6ecb49bf828d83948765ec2d3a579d476bbb9645e749610baa6ec880ca","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"0aef708fb4c7a6b915e8305cbfac40cd207b032dbaabe9a01889a5fff3254681","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"ad9bdafb4e7abf14cc53ce7970486a84c87831e62891e5dfe798ddcd55e84701","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"71d3ae6a5e73ca4130762560425e00984ebaff64d5353a3333d1bb7eb86ef336","impliedFormat":1},{"version":"4371055bb001f40596e2e236b27583e13bf11e75d937962f8947d56519237fb8","impliedFormat":1},{"version":"89189df027e8910200a4b65af1e29a996225cf25975f5c438fbe9361c008fc6b","impliedFormat":1},{"version":"4555baaea5dfc93e0c0ba3fc326b0ba3ad50bb2ab887fa2dff49c7da7bd3bcaa","impliedFormat":1},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1},{"version":"2e23be37a190953f60cdc4a62f89e5dfe4d6c64f38c71564bc0fb63c7810c9a1","impliedFormat":1}],"root":[[65,68]],"options":{"allowUnreachableCode":false,"allowUnusedLabels":false,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noPropertyAccessFromIndexSignature":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./","rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"tsBuildInfoFile":"./.tsbuildinfo","useUnknownInCatchVariables":true,"verbatimModuleSyntax":true},"referencedMap":[[63,1],[62,2],[71,3],[69,2],[179,4],[180,5],[181,2],[124,6],[125,6],[126,7],[77,8],[127,9],[128,10],[129,11],[72,2],[75,12],[73,2],[74,2],[130,13],[131,14],[132,15],[133,16],[134,17],[135,18],[136,18],[137,19],[138,20],[139,21],[140,22],[78,2],[76,2],[141,23],[142,24],[143,25],[177,26],[144,27],[145,2],[146,28],[147,29],[148,30],[149,31],[150,32],[151,33],[152,34],[153,35],[154,36],[155,36],[156,37],[157,2],[158,38],[159,39],[161,40],[160,41],[162,42],[163,43],[164,44],[165,45],[166,46],[167,47],[168,48],[169,49],[170,50],[171,51],[172,52],[173,53],[174,54],[79,2],[80,2],[81,2],[120,55],[121,2],[122,2],[123,42],[175,56],[176,57],[182,58],[178,59],[70,2],[82,2],[64,60],[60,2],[61,2],[12,2],[11,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[19,2],[20,2],[3,2],[21,2],[22,2],[4,2],[23,2],[27,2],[24,2],[25,2],[26,2],[28,2],[29,2],[30,2],[5,2],[31,2],[32,2],[33,2],[34,2],[6,2],[38,2],[35,2],[36,2],[37,2],[39,2],[7,2],[40,2],[45,2],[46,2],[41,2],[42,2],[43,2],[44,2],[8,2],[50,2],[47,2],[48,2],[49,2],[51,2],[9,2],[52,2],[53,2],[54,2],[56,2],[55,2],[57,2],[58,2],[10,2],[59,2],[1,2],[98,61],[108,62],[97,61],[118,63],[89,64],[88,65],[117,66],[111,67],[116,68],[91,69],[105,70],[90,71],[114,72],[86,73],[85,66],[115,74],[87,75],[92,76],[93,2],[96,76],[83,2],[119,77],[109,78],[100,79],[101,80],[103,81],[99,82],[102,83],[112,66],[94,84],[95,85],[104,86],[84,87],[107,78],[106,76],[110,2],[113,88],[65,89],[66,89],[68,90],[67,91]],"latestChangedDtsFile":"./index.d.ts","version":"5.9.3"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route-based selection — the signal that survives a fixture barrel.
|
|
3
|
+
*
|
|
4
|
+
* The import graph says every spec depends on every feature, because they all
|
|
5
|
+
* compose one `test` object. That is *true*, and useless. Two independent
|
|
6
|
+
* facts narrow past it:
|
|
7
|
+
*
|
|
8
|
+
* OWNERSHIP (static) which file navigates to which route — `page.goto('/gyms')`
|
|
9
|
+
* COVERAGE (runtime) which routes each test actually visited
|
|
10
|
+
*
|
|
11
|
+
* Change a file that owns `/gyms`, and the tests worth running are the ones
|
|
12
|
+
* that went to `/gyms`. Neither fact passes through the barrel, so neither is
|
|
13
|
+
* washed out by it.
|
|
14
|
+
*
|
|
15
|
+
* This also fixes the case the import graph can never see: a route sweep that
|
|
16
|
+
* reads its targets from an array imports no page object at all, but its
|
|
17
|
+
* coverage records every route it visited.
|
|
18
|
+
*/
|
|
19
|
+
/** file → routes it navigates to. */
|
|
20
|
+
export type RouteOwnership = ReadonlyMap<string, ReadonlySet<string>>;
|
|
21
|
+
/** spec file → routes its tests visited. */
|
|
22
|
+
export type RouteCoverage = ReadonlyMap<string, ReadonlySet<string>>;
|
|
23
|
+
/**
|
|
24
|
+
* Scan for navigation literals: `page.goto('/gyms')`.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately literal-only. A computed route (`page.goto(url)`) is not
|
|
27
|
+
* guessed at — an ownership claim that might be wrong is worse than no claim,
|
|
28
|
+
* because it would silently narrow the selection to the wrong set.
|
|
29
|
+
*/
|
|
30
|
+
export declare function scanRouteOwnership(tsConfigPath: string, rootDir: string): RouteOwnership;
|
|
31
|
+
/** `http://host/gyms?q=x` and `/gyms` both become `/gyms`. */
|
|
32
|
+
export declare function normaliseRoute(raw: string): string | null;
|
|
33
|
+
export interface CoverageAttempt {
|
|
34
|
+
readonly file: string;
|
|
35
|
+
readonly routes: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
/** Fold attempt records into spec → routes. */
|
|
38
|
+
export declare function buildCoverage(attempts: readonly CoverageAttempt[]): RouteCoverage;
|
|
39
|
+
export interface RouteSelection {
|
|
40
|
+
/** spec → the routes that selected it. */
|
|
41
|
+
readonly selected: ReadonlyMap<string, readonly string[]>;
|
|
42
|
+
/** Routes owned by the changed files. */
|
|
43
|
+
readonly routes: readonly string[];
|
|
44
|
+
/** True when no changed file owns any route — route selection cannot help. */
|
|
45
|
+
readonly noOwnership: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Which specs visited a route owned by one of the changed files.
|
|
49
|
+
*
|
|
50
|
+
* Returns `noOwnership` rather than an empty selection when the diff touches
|
|
51
|
+
* nothing route-bearing: "no spec matched" and "this method does not apply"
|
|
52
|
+
* are different answers, and conflating them would silently skip everything.
|
|
53
|
+
*/
|
|
54
|
+
export declare function selectByRoute(changed: readonly string[], ownership: RouteOwnership, coverage: RouteCoverage): RouteSelection;
|
|
55
|
+
/** Specs with no recorded coverage — they must never be silently dropped. */
|
|
56
|
+
export declare function specsWithoutCoverage(allSpecs: readonly string[], coverage: RouteCoverage): string[];
|
|
57
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,qCAAqC;AACrC,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AAEtE,4CAA4C;AAC5C,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AAIrE;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CA8BxF;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,+CAA+C;AAC/C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,GAAG,aAAa,CAWjF;AAED,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC1D,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,EAAE,cAAc,EACzB,QAAQ,EAAE,aAAa,GACtB,cAAc,CAiBhB;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,QAAQ,EAAE,aAAa,GACtB,MAAM,EAAE,CAEV"}
|
package/dist/coverage.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route-based selection — the signal that survives a fixture barrel.
|
|
3
|
+
*
|
|
4
|
+
* The import graph says every spec depends on every feature, because they all
|
|
5
|
+
* compose one `test` object. That is *true*, and useless. Two independent
|
|
6
|
+
* facts narrow past it:
|
|
7
|
+
*
|
|
8
|
+
* OWNERSHIP (static) which file navigates to which route — `page.goto('/gyms')`
|
|
9
|
+
* COVERAGE (runtime) which routes each test actually visited
|
|
10
|
+
*
|
|
11
|
+
* Change a file that owns `/gyms`, and the tests worth running are the ones
|
|
12
|
+
* that went to `/gyms`. Neither fact passes through the barrel, so neither is
|
|
13
|
+
* washed out by it.
|
|
14
|
+
*
|
|
15
|
+
* This also fixes the case the import graph can never see: a route sweep that
|
|
16
|
+
* reads its targets from an array imports no page object at all, but its
|
|
17
|
+
* coverage records every route it visited.
|
|
18
|
+
*/
|
|
19
|
+
import { Project, SyntaxKind } from 'ts-morph';
|
|
20
|
+
import { relative } from 'node:path';
|
|
21
|
+
const GOTO_METHODS = new Set(['goto', 'navigate']);
|
|
22
|
+
/**
|
|
23
|
+
* Scan for navigation literals: `page.goto('/gyms')`.
|
|
24
|
+
*
|
|
25
|
+
* Deliberately literal-only. A computed route (`page.goto(url)`) is not
|
|
26
|
+
* guessed at — an ownership claim that might be wrong is worse than no claim,
|
|
27
|
+
* because it would silently narrow the selection to the wrong set.
|
|
28
|
+
*/
|
|
29
|
+
export function scanRouteOwnership(tsConfigPath, rootDir) {
|
|
30
|
+
const project = new Project({ tsConfigFilePath: tsConfigPath, skipAddingFilesFromTsConfig: false });
|
|
31
|
+
const ownership = new Map();
|
|
32
|
+
for (const file of project.getSourceFiles()) {
|
|
33
|
+
if (file.isDeclarationFile())
|
|
34
|
+
continue;
|
|
35
|
+
const path = relative(rootDir, file.getFilePath()).split('\\').join('/');
|
|
36
|
+
for (const call of file.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
37
|
+
const expression = call.getExpression();
|
|
38
|
+
if (!expression.isKind(SyntaxKind.PropertyAccessExpression))
|
|
39
|
+
continue;
|
|
40
|
+
if (!GOTO_METHODS.has(expression.getName()))
|
|
41
|
+
continue;
|
|
42
|
+
const first = call.getArguments()[0];
|
|
43
|
+
if (first === undefined)
|
|
44
|
+
continue;
|
|
45
|
+
if (!first.isKind(SyntaxKind.StringLiteral) && !first.isKind(SyntaxKind.NoSubstitutionTemplateLiteral)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const raw = first.getLiteralText();
|
|
49
|
+
const route = normaliseRoute(raw);
|
|
50
|
+
if (route === null)
|
|
51
|
+
continue;
|
|
52
|
+
const existing = ownership.get(path) ?? new Set();
|
|
53
|
+
existing.add(route);
|
|
54
|
+
ownership.set(path, existing);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return ownership;
|
|
58
|
+
}
|
|
59
|
+
/** `http://host/gyms?q=x` and `/gyms` both become `/gyms`. */
|
|
60
|
+
export function normaliseRoute(raw) {
|
|
61
|
+
if (raw === '')
|
|
62
|
+
return null;
|
|
63
|
+
try {
|
|
64
|
+
const url = new URL(raw, 'http://placeholder');
|
|
65
|
+
// about:, data: and blob: are not routes. Without this check
|
|
66
|
+
// `about:blank` normalises to the pathname "blank" and is recorded as
|
|
67
|
+
// though the test had visited a page called that.
|
|
68
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
69
|
+
return null;
|
|
70
|
+
const path = url.pathname;
|
|
71
|
+
return path === '' ? '/' : path;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return raw.startsWith('/') ? (raw.split('?')[0] ?? raw) : null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Fold attempt records into spec → routes. */
|
|
78
|
+
export function buildCoverage(attempts) {
|
|
79
|
+
const coverage = new Map();
|
|
80
|
+
for (const attempt of attempts) {
|
|
81
|
+
if (attempt.routes.length === 0)
|
|
82
|
+
continue;
|
|
83
|
+
const existing = coverage.get(attempt.file) ?? new Set();
|
|
84
|
+
for (const route of attempt.routes)
|
|
85
|
+
existing.add(route);
|
|
86
|
+
coverage.set(attempt.file, existing);
|
|
87
|
+
}
|
|
88
|
+
return coverage;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Which specs visited a route owned by one of the changed files.
|
|
92
|
+
*
|
|
93
|
+
* Returns `noOwnership` rather than an empty selection when the diff touches
|
|
94
|
+
* nothing route-bearing: "no spec matched" and "this method does not apply"
|
|
95
|
+
* are different answers, and conflating them would silently skip everything.
|
|
96
|
+
*/
|
|
97
|
+
export function selectByRoute(changed, ownership, coverage) {
|
|
98
|
+
const routes = new Set();
|
|
99
|
+
for (const file of changed) {
|
|
100
|
+
for (const route of ownership.get(file) ?? [])
|
|
101
|
+
routes.add(route);
|
|
102
|
+
}
|
|
103
|
+
if (routes.size === 0) {
|
|
104
|
+
return { selected: new Map(), routes: [], noOwnership: true };
|
|
105
|
+
}
|
|
106
|
+
const selected = new Map();
|
|
107
|
+
for (const [spec, visited] of coverage) {
|
|
108
|
+
const hits = [...visited].filter(route => routes.has(route));
|
|
109
|
+
if (hits.length > 0)
|
|
110
|
+
selected.set(spec, hits.sort());
|
|
111
|
+
}
|
|
112
|
+
return { selected, routes: [...routes].sort(), noOwnership: false };
|
|
113
|
+
}
|
|
114
|
+
/** Specs with no recorded coverage — they must never be silently dropped. */
|
|
115
|
+
export function specsWithoutCoverage(allSpecs, coverage) {
|
|
116
|
+
return allSpecs.filter(spec => !coverage.has(spec)).sort();
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The static import graph.
|
|
3
|
+
*
|
|
4
|
+
* Answers "which specs could a change to this file possibly affect?" by
|
|
5
|
+
* walking import edges backwards. Deterministic, explainable, and fast enough
|
|
6
|
+
* to run on every pull request — which is why this, and not a model, decides
|
|
7
|
+
* what runs.
|
|
8
|
+
*
|
|
9
|
+
* Path aliases (`@ui/*`, `@shared/*`) resolve through the project's own
|
|
10
|
+
* tsconfig: ts-morph asks the TypeScript compiler, so whatever the suite
|
|
11
|
+
* compiles against is what the graph sees.
|
|
12
|
+
*/
|
|
13
|
+
export interface GraphOptions {
|
|
14
|
+
readonly tsConfigPath: string;
|
|
15
|
+
readonly rootDir: string;
|
|
16
|
+
/** Files matching this are treated as test entry points. */
|
|
17
|
+
readonly specPattern: RegExp;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_SPEC_PATTERN: RegExp;
|
|
20
|
+
export interface ImportGraph {
|
|
21
|
+
/** Repo-relative spec paths. */
|
|
22
|
+
readonly specs: readonly string[];
|
|
23
|
+
/** file → files that import it, directly. */
|
|
24
|
+
readonly importers: ReadonlyMap<string, ReadonlySet<string>>;
|
|
25
|
+
readonly fileCount: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function buildGraph(options: GraphOptions): ImportGraph;
|
|
28
|
+
/**
|
|
29
|
+
* Every spec reachable from the changed files by following imports backwards.
|
|
30
|
+
*
|
|
31
|
+
* Returns the path that selected each spec, not just the set. A selection
|
|
32
|
+
* nobody can explain is a coverage hole waiting to happen, and "why did this
|
|
33
|
+
* run?" has to be answerable without reading the implementation.
|
|
34
|
+
*/
|
|
35
|
+
export declare function affectedSpecs(graph: ImportGraph, changed: readonly string[]): Map<string, string[]>;
|
|
36
|
+
export interface HubFile {
|
|
37
|
+
readonly file: string;
|
|
38
|
+
/** Share of all specs that reach this file. */
|
|
39
|
+
readonly reach: number;
|
|
40
|
+
readonly specCount: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Files that nearly every spec depends on — barrels, composed fixtures,
|
|
44
|
+
* shared config.
|
|
45
|
+
*
|
|
46
|
+
* These defeat static test selection, and saying so is the whole point of
|
|
47
|
+
* detecting them. A suite that composes all feature fixtures into one `test`
|
|
48
|
+
* export gives every spec a real dependency on every feature: change one
|
|
49
|
+
* feature's page object and the graph correctly, uselessly, selects almost
|
|
50
|
+
* everything. Reporting the hub explains WHY a selection did not narrow,
|
|
51
|
+
* instead of leaving someone to conclude the tool is broken.
|
|
52
|
+
*
|
|
53
|
+
* @param graph - Import graph from `buildGraph`.
|
|
54
|
+
* @param threshold - Share of specs a file must reach to count as a hub.
|
|
55
|
+
* @param minSpecs - Below this, "most specs" is not meaningful: in a two-spec
|
|
56
|
+
* project anything reaching one spec is 50%, and calling that a hub would
|
|
57
|
+
* suppress selection entirely.
|
|
58
|
+
*/
|
|
59
|
+
export declare function hubFiles(graph: ImportGraph, threshold?: number, minSpecs?: number): HubFile[];
|
|
60
|
+
/**
|
|
61
|
+
* Does this change reach specs ONLY by passing through a hub?
|
|
62
|
+
*
|
|
63
|
+
* If so the selection is not meaningfully narrower than the whole suite, and
|
|
64
|
+
* the honest answer is to run everything rather than to present a number that
|
|
65
|
+
* looks like discrimination and is not.
|
|
66
|
+
*/
|
|
67
|
+
export declare function reachesOnlyViaHubs(paths: ReadonlyMap<string, readonly string[]>, hubs: readonly HubFile[]): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Specs the graph cannot reason about.
|
|
70
|
+
*
|
|
71
|
+
* A spec that imports almost nothing — an accessibility sweep iterating routes
|
|
72
|
+
* from an array, for instance — has no import edge to the page objects it
|
|
73
|
+
* exercises. The graph will never select it, and quietly dropping it is
|
|
74
|
+
* exactly the silent coverage loss that makes teams distrust test selection.
|
|
75
|
+
* These are reported so they can be forced to always run.
|
|
76
|
+
*/
|
|
77
|
+
export declare function unattributableSpecs(graph: ImportGraph, minEdges?: number): string[];
|
|
78
|
+
export declare function resolveTsConfig(rootDir: string, provided?: string): string;
|
|
79
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,oBAAoB,QAAyB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAMD,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CA2B7D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAuBvB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,SAAM,EAAE,QAAQ,SAAI,GAAG,OAAO,EAAE,CAarF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EAC7C,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,OAAO,CAIT;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,SAAI,GAAG,MAAM,EAAE,CAY9E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1E"}
|
package/dist/graph.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The static import graph.
|
|
3
|
+
*
|
|
4
|
+
* Answers "which specs could a change to this file possibly affect?" by
|
|
5
|
+
* walking import edges backwards. Deterministic, explainable, and fast enough
|
|
6
|
+
* to run on every pull request — which is why this, and not a model, decides
|
|
7
|
+
* what runs.
|
|
8
|
+
*
|
|
9
|
+
* Path aliases (`@ui/*`, `@shared/*`) resolve through the project's own
|
|
10
|
+
* tsconfig: ts-morph asks the TypeScript compiler, so whatever the suite
|
|
11
|
+
* compiles against is what the graph sees.
|
|
12
|
+
*/
|
|
13
|
+
import { relative, resolve } from 'node:path';
|
|
14
|
+
import { Project } from 'ts-morph';
|
|
15
|
+
export const DEFAULT_SPEC_PATTERN = /\.(spec|test)\.tsx?$/;
|
|
16
|
+
function toRelative(rootDir, file) {
|
|
17
|
+
return relative(rootDir, file).split('\\').join('/');
|
|
18
|
+
}
|
|
19
|
+
export function buildGraph(options) {
|
|
20
|
+
const project = new Project({
|
|
21
|
+
tsConfigFilePath: options.tsConfigPath,
|
|
22
|
+
skipAddingFilesFromTsConfig: false,
|
|
23
|
+
});
|
|
24
|
+
const importers = new Map();
|
|
25
|
+
const specs = [];
|
|
26
|
+
const sourceFiles = project.getSourceFiles().filter((f) => !f.isDeclarationFile());
|
|
27
|
+
for (const file of sourceFiles) {
|
|
28
|
+
const importer = toRelative(options.rootDir, file.getFilePath());
|
|
29
|
+
if (options.specPattern.test(importer))
|
|
30
|
+
specs.push(importer);
|
|
31
|
+
// getReferencedSourceFiles resolves through the compiler, so path aliases
|
|
32
|
+
// and index files are handled the same way the suite itself resolves them.
|
|
33
|
+
for (const referenced of file.getReferencedSourceFiles()) {
|
|
34
|
+
const path = referenced.getFilePath();
|
|
35
|
+
if (path.includes('node_modules'))
|
|
36
|
+
continue;
|
|
37
|
+
const target = toRelative(options.rootDir, path);
|
|
38
|
+
const existing = importers.get(target) ?? new Set();
|
|
39
|
+
existing.add(importer);
|
|
40
|
+
importers.set(target, existing);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { specs: specs.sort(), importers, fileCount: sourceFiles.length };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Every spec reachable from the changed files by following imports backwards.
|
|
47
|
+
*
|
|
48
|
+
* Returns the path that selected each spec, not just the set. A selection
|
|
49
|
+
* nobody can explain is a coverage hole waiting to happen, and "why did this
|
|
50
|
+
* run?" has to be answerable without reading the implementation.
|
|
51
|
+
*/
|
|
52
|
+
export function affectedSpecs(graph, changed) {
|
|
53
|
+
const affected = new Map();
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
const queue = changed.map(file => ({ file, path: [file] }));
|
|
56
|
+
while (queue.length > 0) {
|
|
57
|
+
const next = queue.shift();
|
|
58
|
+
if (next === undefined)
|
|
59
|
+
continue;
|
|
60
|
+
if (seen.has(next.file))
|
|
61
|
+
continue;
|
|
62
|
+
seen.add(next.file);
|
|
63
|
+
if (graph.specs.includes(next.file)) {
|
|
64
|
+
affected.set(next.file, next.path);
|
|
65
|
+
// A spec is a leaf: nothing imports it, so there is nowhere further to walk.
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const importer of graph.importers.get(next.file) ?? []) {
|
|
69
|
+
if (!seen.has(importer))
|
|
70
|
+
queue.push({ file: importer, path: [...next.path, importer] });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return affected;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Files that nearly every spec depends on — barrels, composed fixtures,
|
|
77
|
+
* shared config.
|
|
78
|
+
*
|
|
79
|
+
* These defeat static test selection, and saying so is the whole point of
|
|
80
|
+
* detecting them. A suite that composes all feature fixtures into one `test`
|
|
81
|
+
* export gives every spec a real dependency on every feature: change one
|
|
82
|
+
* feature's page object and the graph correctly, uselessly, selects almost
|
|
83
|
+
* everything. Reporting the hub explains WHY a selection did not narrow,
|
|
84
|
+
* instead of leaving someone to conclude the tool is broken.
|
|
85
|
+
*
|
|
86
|
+
* @param graph - Import graph from `buildGraph`.
|
|
87
|
+
* @param threshold - Share of specs a file must reach to count as a hub.
|
|
88
|
+
* @param minSpecs - Below this, "most specs" is not meaningful: in a two-spec
|
|
89
|
+
* project anything reaching one spec is 50%, and calling that a hub would
|
|
90
|
+
* suppress selection entirely.
|
|
91
|
+
*/
|
|
92
|
+
export function hubFiles(graph, threshold = 0.8, minSpecs = 5) {
|
|
93
|
+
const total = graph.specs.length;
|
|
94
|
+
if (total < minSpecs)
|
|
95
|
+
return [];
|
|
96
|
+
const hubs = [];
|
|
97
|
+
for (const file of graph.importers.keys()) {
|
|
98
|
+
if (graph.specs.includes(file))
|
|
99
|
+
continue;
|
|
100
|
+
const reached = affectedSpecs(graph, [file]).size;
|
|
101
|
+
const reach = reached / total;
|
|
102
|
+
if (reach >= threshold)
|
|
103
|
+
hubs.push({ file, reach, specCount: reached });
|
|
104
|
+
}
|
|
105
|
+
return hubs.sort((a, b) => b.reach - a.reach);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Does this change reach specs ONLY by passing through a hub?
|
|
109
|
+
*
|
|
110
|
+
* If so the selection is not meaningfully narrower than the whole suite, and
|
|
111
|
+
* the honest answer is to run everything rather than to present a number that
|
|
112
|
+
* looks like discrimination and is not.
|
|
113
|
+
*/
|
|
114
|
+
export function reachesOnlyViaHubs(paths, hubs) {
|
|
115
|
+
if (paths.size === 0 || hubs.length === 0)
|
|
116
|
+
return false;
|
|
117
|
+
const hubPaths = new Set(hubs.map(h => h.file));
|
|
118
|
+
return [...paths.values()].every(path => path.some(step => hubPaths.has(step)));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Specs the graph cannot reason about.
|
|
122
|
+
*
|
|
123
|
+
* A spec that imports almost nothing — an accessibility sweep iterating routes
|
|
124
|
+
* from an array, for instance — has no import edge to the page objects it
|
|
125
|
+
* exercises. The graph will never select it, and quietly dropping it is
|
|
126
|
+
* exactly the silent coverage loss that makes teams distrust test selection.
|
|
127
|
+
* These are reported so they can be forced to always run.
|
|
128
|
+
*/
|
|
129
|
+
export function unattributableSpecs(graph, minEdges = 2) {
|
|
130
|
+
const outgoing = new Map();
|
|
131
|
+
for (const [target, importerSet] of graph.importers) {
|
|
132
|
+
for (const importer of importerSet) {
|
|
133
|
+
if (!graph.specs.includes(importer))
|
|
134
|
+
continue;
|
|
135
|
+
void target;
|
|
136
|
+
outgoing.set(importer, (outgoing.get(importer) ?? 0) + 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return graph.specs.filter(spec => (outgoing.get(spec) ?? 0) < minEdges).sort();
|
|
140
|
+
}
|
|
141
|
+
export function resolveTsConfig(rootDir, provided) {
|
|
142
|
+
return provided === undefined ? resolve(rootDir, 'tsconfig.json') : resolve(provided);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aplaytest/impact — test selection from a static import graph.
|
|
3
|
+
*
|
|
4
|
+
* Entirely deterministic. The one place a model could help is mapping a diff
|
|
5
|
+
* in ANOTHER repository (the application) onto tests here, where no import
|
|
6
|
+
* edge exists — and even there it may only ADD tests, never remove them, so a
|
|
7
|
+
* model error costs CI minutes rather than coverage.
|
|
8
|
+
*/
|
|
9
|
+
export { buildGraph, affectedSpecs, unattributableSpecs, hubFiles, reachesOnlyViaHubs, resolveTsConfig, DEFAULT_SPEC_PATTERN, } from './graph.js';
|
|
10
|
+
export type { ImportGraph, GraphOptions, HubFile } from './graph.js';
|
|
11
|
+
export { selectTests, toPlaywrightArgs, DEFAULT_SELECTION_CONFIG } from './select.js';
|
|
12
|
+
export type { Selection, SelectionConfig, SelectionReason, SelectionMode } from './select.js';
|
|
13
|
+
export { scanRouteOwnership, buildCoverage, selectByRoute, specsWithoutCoverage, normaliseRoute, } from './coverage.js';
|
|
14
|
+
export type { RouteOwnership, RouteCoverage, RouteSelection, CoverageAttempt } from './coverage.js';
|
|
15
|
+
export type { RouteInputs } from './select.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACtF,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE9F,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACpG,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aplaytest/impact — test selection from a static import graph.
|
|
3
|
+
*
|
|
4
|
+
* Entirely deterministic. The one place a model could help is mapping a diff
|
|
5
|
+
* in ANOTHER repository (the application) onto tests here, where no import
|
|
6
|
+
* edge exists — and even there it may only ADD tests, never remove them, so a
|
|
7
|
+
* model error costs CI minutes rather than coverage.
|
|
8
|
+
*/
|
|
9
|
+
export { buildGraph, affectedSpecs, unattributableSpecs, hubFiles, reachesOnlyViaHubs, resolveTsConfig, DEFAULT_SPEC_PATTERN, } from './graph.js';
|
|
10
|
+
export { selectTests, toPlaywrightArgs, DEFAULT_SELECTION_CONFIG } from './select.js';
|
|
11
|
+
export { scanRouteOwnership, buildCoverage, selectByRoute, specsWithoutCoverage, normaliseRoute, } from './coverage.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAGtF,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,cAAc,GACf,MAAM,eAAe,CAAC"}
|
package/dist/select.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test selection.
|
|
3
|
+
*
|
|
4
|
+
* The guards matter more than the graph. Impact analysis trades coverage for
|
|
5
|
+
* latency, and every rule here exists to bound what that trade can cost:
|
|
6
|
+
*
|
|
7
|
+
* · `main` runs everything. Selection is a pull-request optimisation only.
|
|
8
|
+
* · Smoke always runs. It is the floor, and it is cheap.
|
|
9
|
+
* · Some paths trigger the full suite outright — configuration, shared
|
|
10
|
+
* modules, lockfiles. Cheap insurance against a clever-but-wrong selection.
|
|
11
|
+
* · Above a threshold share, run everything. The saving stops justifying
|
|
12
|
+
* the risk long before it reaches 100%.
|
|
13
|
+
* · Specs the graph cannot attribute are always run, never dropped.
|
|
14
|
+
*
|
|
15
|
+
* A model is not involved and does not need to be.
|
|
16
|
+
*/
|
|
17
|
+
import { type RouteCoverage, type RouteOwnership } from './coverage.js';
|
|
18
|
+
import { type HubFile, type ImportGraph } from './graph.js';
|
|
19
|
+
export type SelectionMode = 'full' | 'partial';
|
|
20
|
+
export interface SelectionConfig {
|
|
21
|
+
/** Changing any of these runs everything. */
|
|
22
|
+
readonly fullSuiteTriggers: readonly string[];
|
|
23
|
+
/** Above this share of all specs, just run everything. */
|
|
24
|
+
readonly fullSuiteThreshold: number;
|
|
25
|
+
/** Specs matching these always run regardless of the diff. */
|
|
26
|
+
readonly alwaysRun: readonly string[];
|
|
27
|
+
/** Treat unattributable specs as always-run rather than dropping them. */
|
|
28
|
+
readonly runUnattributable: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare const DEFAULT_SELECTION_CONFIG: SelectionConfig;
|
|
31
|
+
export interface SelectionReason {
|
|
32
|
+
readonly spec: string;
|
|
33
|
+
readonly reason: 'always-run' | 'unattributable' | 'imports-changed-file' | 'visited-route' | 'no-coverage';
|
|
34
|
+
/** The import chain that selected it, changed file first. */
|
|
35
|
+
readonly via: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
export interface Selection {
|
|
38
|
+
readonly mode: SelectionMode;
|
|
39
|
+
/** Files nearly every spec depends on, which defeat narrowing. */
|
|
40
|
+
readonly hubs: readonly HubFile[];
|
|
41
|
+
/** Why the whole suite is running, when it is. */
|
|
42
|
+
readonly fullSuiteReason: string | null;
|
|
43
|
+
readonly selected: readonly string[];
|
|
44
|
+
readonly reasons: readonly SelectionReason[];
|
|
45
|
+
readonly totalSpecs: number;
|
|
46
|
+
readonly changed: readonly string[];
|
|
47
|
+
}
|
|
48
|
+
export interface RouteInputs {
|
|
49
|
+
readonly ownership: RouteOwnership;
|
|
50
|
+
readonly coverage: RouteCoverage;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Select which specs a diff should run.
|
|
54
|
+
*
|
|
55
|
+
* Guards bound what the import-graph trade can cost: full-suite triggers,
|
|
56
|
+
* hubs, unattributable specs, and an optional route-coverage signal that
|
|
57
|
+
* survives a shared fixture barrel. A model is not involved.
|
|
58
|
+
*
|
|
59
|
+
* @param graph - Import graph from `buildGraph`.
|
|
60
|
+
* @param changed - Repo-relative paths that changed.
|
|
61
|
+
* @param config - Triggers, always-run tags, and the full-suite threshold.
|
|
62
|
+
* @param routeInputs - Optional ownership + coverage, used before the graph
|
|
63
|
+
* when present.
|
|
64
|
+
* @returns Either a partial selection with a reason per spec, or `mode: 'full'`
|
|
65
|
+
* with an explanation of why nothing was skipped.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const graph = buildGraph({ rootDir: process.cwd() });
|
|
70
|
+
* const selection = selectTests(graph, ['src/pages/gyms.page.ts']);
|
|
71
|
+
* await playwright.test(toPlaywrightArgs(selection));
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function selectTests(graph: ImportGraph, changed: readonly string[], config?: SelectionConfig, routeInputs?: RouteInputs): Selection;
|
|
75
|
+
/** A Playwright-ready argument list for the selection. */
|
|
76
|
+
export declare function toPlaywrightArgs(selection: Selection): string[];
|
|
77
|
+
//# sourceMappingURL=select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAKL,KAAK,OAAO,EACZ,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,0DAA0D;IAC1D,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC;AAED,eAAO,MAAM,wBAAwB,EAAE,eAatC,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,GAAG,sBAAsB,GAAG,eAAe,GAAG,aAAa,CAAC;IAC5G,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,kDAAkD;IAClD,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAYD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,MAAM,GAAE,eAA0C,EAClD,WAAW,CAAC,EAAE,WAAW,GACxB,SAAS,CAsJX;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,CAE/D"}
|
package/dist/select.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test selection.
|
|
3
|
+
*
|
|
4
|
+
* The guards matter more than the graph. Impact analysis trades coverage for
|
|
5
|
+
* latency, and every rule here exists to bound what that trade can cost:
|
|
6
|
+
*
|
|
7
|
+
* · `main` runs everything. Selection is a pull-request optimisation only.
|
|
8
|
+
* · Smoke always runs. It is the floor, and it is cheap.
|
|
9
|
+
* · Some paths trigger the full suite outright — configuration, shared
|
|
10
|
+
* modules, lockfiles. Cheap insurance against a clever-but-wrong selection.
|
|
11
|
+
* · Above a threshold share, run everything. The saving stops justifying
|
|
12
|
+
* the risk long before it reaches 100%.
|
|
13
|
+
* · Specs the graph cannot attribute are always run, never dropped.
|
|
14
|
+
*
|
|
15
|
+
* A model is not involved and does not need to be.
|
|
16
|
+
*/
|
|
17
|
+
import { selectByRoute, specsWithoutCoverage, } from './coverage.js';
|
|
18
|
+
import { affectedSpecs, hubFiles, reachesOnlyViaHubs, unattributableSpecs, } from './graph.js';
|
|
19
|
+
export const DEFAULT_SELECTION_CONFIG = {
|
|
20
|
+
fullSuiteTriggers: [
|
|
21
|
+
'package.json',
|
|
22
|
+
'package-lock.json',
|
|
23
|
+
'pnpm-lock.yaml',
|
|
24
|
+
'tsconfig.json',
|
|
25
|
+
'playwright.config.ts',
|
|
26
|
+
'atest.config.ts',
|
|
27
|
+
'Dockerfile',
|
|
28
|
+
],
|
|
29
|
+
fullSuiteThreshold: 0.6,
|
|
30
|
+
alwaysRun: [],
|
|
31
|
+
runUnattributable: true,
|
|
32
|
+
};
|
|
33
|
+
function matchesAny(path, patterns) {
|
|
34
|
+
return patterns.some(pattern => {
|
|
35
|
+
if (pattern.includes('*')) {
|
|
36
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*\*/g, '.*').replace(/(?<!\.)\*/g, '[^/]*');
|
|
37
|
+
return new RegExp(`^${escaped}$`).test(path);
|
|
38
|
+
}
|
|
39
|
+
return path === pattern || path.endsWith(`/${pattern}`);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Select which specs a diff should run.
|
|
44
|
+
*
|
|
45
|
+
* Guards bound what the import-graph trade can cost: full-suite triggers,
|
|
46
|
+
* hubs, unattributable specs, and an optional route-coverage signal that
|
|
47
|
+
* survives a shared fixture barrel. A model is not involved.
|
|
48
|
+
*
|
|
49
|
+
* @param graph - Import graph from `buildGraph`.
|
|
50
|
+
* @param changed - Repo-relative paths that changed.
|
|
51
|
+
* @param config - Triggers, always-run tags, and the full-suite threshold.
|
|
52
|
+
* @param routeInputs - Optional ownership + coverage, used before the graph
|
|
53
|
+
* when present.
|
|
54
|
+
* @returns Either a partial selection with a reason per spec, or `mode: 'full'`
|
|
55
|
+
* with an explanation of why nothing was skipped.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const graph = buildGraph({ rootDir: process.cwd() });
|
|
60
|
+
* const selection = selectTests(graph, ['src/pages/gyms.page.ts']);
|
|
61
|
+
* await playwright.test(toPlaywrightArgs(selection));
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export function selectTests(graph, changed, config = DEFAULT_SELECTION_CONFIG, routeInputs) {
|
|
65
|
+
const total = graph.specs.length;
|
|
66
|
+
const trigger = changed.find(path => matchesAny(path, config.fullSuiteTriggers));
|
|
67
|
+
if (trigger !== undefined) {
|
|
68
|
+
return {
|
|
69
|
+
mode: 'full',
|
|
70
|
+
fullSuiteReason: `${trigger} changed — that reaches everything, so nothing is skipped.`,
|
|
71
|
+
selected: graph.specs,
|
|
72
|
+
reasons: [],
|
|
73
|
+
totalSpecs: total,
|
|
74
|
+
changed,
|
|
75
|
+
hubs: [],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const hubs = hubFiles(graph);
|
|
79
|
+
const paths = affectedSpecs(graph, changed);
|
|
80
|
+
// Route selection FIRST, when the data exists. It is the only signal that
|
|
81
|
+
// survives a shared fixture barrel, so trying it before falling back to the
|
|
82
|
+
// import graph is what makes selection possible at all in such a suite.
|
|
83
|
+
if (routeInputs !== undefined) {
|
|
84
|
+
const byRoute = selectByRoute(changed, routeInputs.ownership, routeInputs.coverage);
|
|
85
|
+
if (!byRoute.noOwnership) {
|
|
86
|
+
const reasons = [];
|
|
87
|
+
const selected = new Set();
|
|
88
|
+
for (const spec of graph.specs) {
|
|
89
|
+
if (matchesAny(spec, config.alwaysRun)) {
|
|
90
|
+
selected.add(spec);
|
|
91
|
+
reasons.push({ spec, reason: 'always-run', via: [] });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// A spec with no recorded coverage has never been observed, so nothing
|
|
95
|
+
// is known about it. Dropping it would be a guess dressed as a decision.
|
|
96
|
+
for (const spec of specsWithoutCoverage(graph.specs, routeInputs.coverage)) {
|
|
97
|
+
if (selected.has(spec))
|
|
98
|
+
continue;
|
|
99
|
+
selected.add(spec);
|
|
100
|
+
reasons.push({ spec, reason: 'no-coverage', via: [] });
|
|
101
|
+
}
|
|
102
|
+
for (const [spec, routes] of byRoute.selected) {
|
|
103
|
+
// Coverage can name a spec the graph does not know about — a deleted
|
|
104
|
+
// file, or a path recorded in a different form. Selecting something
|
|
105
|
+
// that is not in the suite is how "3/2 selected" happens.
|
|
106
|
+
if (selected.has(spec) || !graph.specs.includes(spec))
|
|
107
|
+
continue;
|
|
108
|
+
selected.add(spec);
|
|
109
|
+
reasons.push({ spec, reason: 'visited-route', via: routes });
|
|
110
|
+
}
|
|
111
|
+
if (total > 0 && selected.size / total > config.fullSuiteThreshold) {
|
|
112
|
+
return {
|
|
113
|
+
mode: 'full',
|
|
114
|
+
fullSuiteReason: `${selected.size}/${total} specs selected by route coverage, above the ` +
|
|
115
|
+
`${(config.fullSuiteThreshold * 100).toFixed(0)}% threshold.`,
|
|
116
|
+
selected: graph.specs,
|
|
117
|
+
reasons,
|
|
118
|
+
totalSpecs: total,
|
|
119
|
+
changed,
|
|
120
|
+
hubs,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
mode: 'partial',
|
|
125
|
+
fullSuiteReason: null,
|
|
126
|
+
selected: [...selected].sort(),
|
|
127
|
+
reasons: reasons.sort((a, b) => a.spec.localeCompare(b.spec)),
|
|
128
|
+
totalSpecs: total,
|
|
129
|
+
changed,
|
|
130
|
+
hubs,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// If every route from the diff to a spec runs through a hub, the graph has
|
|
135
|
+
// not actually discriminated — it has just confirmed that everything
|
|
136
|
+
// depends on the hub. Presenting that as a narrowed selection would be a
|
|
137
|
+
// number that looks like insight and is not.
|
|
138
|
+
if (reachesOnlyViaHubs(paths, hubs)) {
|
|
139
|
+
const worst = hubs[0];
|
|
140
|
+
return {
|
|
141
|
+
mode: 'full',
|
|
142
|
+
fullSuiteReason: `every affected spec reaches this change only through ${worst?.file ?? 'a shared module'}, ` +
|
|
143
|
+
`which ${((worst?.reach ?? 0) * 100).toFixed(0)}% of specs import. Static analysis cannot ` +
|
|
144
|
+
'narrow past a hub like that — runtime coverage could.',
|
|
145
|
+
selected: graph.specs,
|
|
146
|
+
reasons: [],
|
|
147
|
+
totalSpecs: total,
|
|
148
|
+
changed,
|
|
149
|
+
hubs,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const reasons = [];
|
|
153
|
+
const selected = new Set();
|
|
154
|
+
for (const spec of graph.specs) {
|
|
155
|
+
if (matchesAny(spec, config.alwaysRun)) {
|
|
156
|
+
selected.add(spec);
|
|
157
|
+
reasons.push({ spec, reason: 'always-run', via: [] });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (config.runUnattributable) {
|
|
161
|
+
for (const spec of unattributableSpecs(graph)) {
|
|
162
|
+
if (selected.has(spec))
|
|
163
|
+
continue;
|
|
164
|
+
selected.add(spec);
|
|
165
|
+
reasons.push({ spec, reason: 'unattributable', via: [] });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const [spec, path] of paths) {
|
|
169
|
+
if (selected.has(spec))
|
|
170
|
+
continue;
|
|
171
|
+
selected.add(spec);
|
|
172
|
+
reasons.push({ spec, reason: 'imports-changed-file', via: path });
|
|
173
|
+
}
|
|
174
|
+
// Past the threshold the bookkeeping stops being worth the risk: a
|
|
175
|
+
// near-full run that skips a handful of tests carries all the danger of
|
|
176
|
+
// selection and almost none of the saving.
|
|
177
|
+
if (total > 0 && selected.size / total > config.fullSuiteThreshold) {
|
|
178
|
+
return {
|
|
179
|
+
mode: 'full',
|
|
180
|
+
fullSuiteReason: `${selected.size}/${total} specs selected, above the ` +
|
|
181
|
+
`${(config.fullSuiteThreshold * 100).toFixed(0)}% threshold — running everything is safer ` +
|
|
182
|
+
'and barely slower.',
|
|
183
|
+
selected: graph.specs,
|
|
184
|
+
reasons,
|
|
185
|
+
totalSpecs: total,
|
|
186
|
+
changed,
|
|
187
|
+
hubs,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
mode: 'partial',
|
|
192
|
+
fullSuiteReason: null,
|
|
193
|
+
selected: [...selected].sort(),
|
|
194
|
+
reasons: reasons.sort((a, b) => a.spec.localeCompare(b.spec)),
|
|
195
|
+
totalSpecs: total,
|
|
196
|
+
changed,
|
|
197
|
+
hubs,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/** A Playwright-ready argument list for the selection. */
|
|
201
|
+
export function toPlaywrightArgs(selection) {
|
|
202
|
+
return selection.mode === 'full' ? [] : [...selection.selected];
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aplaytest/impact",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Test impact analysis: static import graph and selection",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc --build",
|
|
14
|
+
"test": "vitest run"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@aplaytest/core": "^0.1.0",
|
|
18
|
+
"ts-morph": "^28.0.0"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/ianoflynnautomation/aplaytest.git",
|
|
32
|
+
"directory": "packages/impact"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/ianoflynnautomation/aplaytest#readme",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/ianoflynnautomation/aplaytest/issues"
|
|
37
|
+
}
|
|
38
|
+
}
|