diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 20c81f4..d1588b1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,11 +1,11 @@ { - "name": "vscode-phpunit", - "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm", - "features": { - "ghcr.io/devcontainers/features/php": { - "version": "latest", - "installComposer": true - } - }, - "postStartCommand": "npm install && npm run build" + "name": "vscode-phpunit", + "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm", + "features": { + "ghcr.io/devcontainers/features/php": { + "version": "latest", + "installComposer": true + } + }, + "postStartCommand": "npm install && npm run build" } diff --git a/.editorconfig b/.editorconfig index c1031ee..201ed8d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,4 +4,4 @@ root = true end_of_line = crlf insert_final_newline = true indent_style = space -indent_size = 2 \ No newline at end of file +indent_size = 2 diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 60cf47b..b2dbf4c 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -2,29 +2,35 @@ name: Bug report about: Create a report to help us improve --- + ## Repro + 1. … 2. … 3. … ## Outcome + … ## Expected outcome + … ## Logs / output / settings + + … -| **Environment** | **Values** | -|---|---| -| *Extension version* | … | -| *Operating system* | … | \ No newline at end of file +| **Environment** | **Values** | +| ------------------- | ---------- | +| _Extension version_ | … | +| _Operating system_ | … | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 918b6ea..1d3067c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,7 @@ permissions: on: push: tags: - - '[0-9]+.[0-9]+.[0-9]+' # Minor version should be even for release and odd for pre-release + - "[0-9]+.[0-9]+.[0-9]+" # Minor version should be even for release and odd for pre-release jobs: create_release: diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..1bda9c1 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm run format diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b43bf86 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +README.md diff --git a/.vscode/launch.json b/.vscode/launch.json index fa0c1b4..c12a63f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,44 +1,38 @@ // A launch configuration that compiles the extension and then opens it inside a new window { - "version": "0.2.0", - "configurations": [ - { - "name": "Launch Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--disable-extensions", - "--extensionDevelopmentPath=${workspaceRoot}", - "${workspaceRoot}/src/test/php-project" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js", - "!**/node_modules/**" - ], - "sourceMaps": true, - "preLaunchTask": "npm", - "smartStep": true - }, - { - "name": "Launch Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test/suite/index", - "${workspaceRoot}/src/test/php-project" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js", - "!**/node_modules/**" - ], - "sourceMaps": true, - "preLaunchTask": "npm", - "env": { - "VSCODE_PHPUNIT_TEST": "true" - } - } - ] + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--disable-extensions", + "--extensionDevelopmentPath=${workspaceRoot}", + "${workspaceRoot}/src/test/php-project" + ], + "outFiles": ["${workspaceFolder}/out/**/*.js", "!**/node_modules/**"], + "sourceMaps": true, + "preLaunchTask": "npm", + "smartStep": true + }, + { + "name": "Launch Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}", + "--extensionTestsPath=${workspaceRoot}/out/test/suite/index", + "${workspaceRoot}/src/test/php-project" + ], + "outFiles": ["${workspaceFolder}/out/**/*.js", "!**/node_modules/**"], + "sourceMaps": true, + "preLaunchTask": "npm", + "env": { + "VSCODE_PHPUNIT_TEST": "true" + } + } + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index f514fb7..ccb5a9f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,14 +1,14 @@ // Place your settings in this file to overwrite default and user settings. { - "files.exclude": { - "out": false, // set this to true to hide the "out" folder with the compiled JS files - "**/*.js": true, - "**/*.js.map": true - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - "typescript.tsdk": "./node_modules/typescript/lib", - "FSharp.suggestGitignore": false, - "cmake.configureOnOpen": false // we want to use the TS server from our node_modules folder to control its version -} \ No newline at end of file + "files.exclude": { + "out": false, // set this to true to hide the "out" folder with the compiled JS files + "**/*.js": true, + "**/*.js.map": true + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + "typescript.tsdk": "./node_modules/typescript/lib", + "FSharp.suggestGitignore": false, + "cmake.configureOnOpen": false // we want to use the TS server from our node_modules folder to control its version +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4fff269..bab06e7 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -8,36 +8,31 @@ // A task runner that calls a custom npm script that compiles the extension. { - "version": "2.0.0", + "version": "2.0.0", - // we want to run npm - "command": "npm", + // we want to run npm + "command": "npm", - // we run the custom script "compile" as defined in package.json - "args": ["run", "compile", "--loglevel", "silent"], + // we run the custom script "compile" as defined in package.json + "args": ["run", "compile", "--loglevel", "silent"], - // The tsc compiler is started in watching mode - "isWatching": true, + // The tsc compiler is started in watching mode + "isWatching": true, - // use the standard tsc in watch mode problem matcher to find compile problems in the output. - "problemMatcher": "$tsc-watch", - "tasks": [ - { - "label": "npm", - "type": "shell", - "command": "npm", - "args": [ - "run", - "compile", - "--loglevel", - "silent" - ], - "isBackground": true, - "problemMatcher": "$tsc-watch", - "group": { - "_id": "build", - "isDefault": false - } - } - ] -} \ No newline at end of file + // use the standard tsc in watch mode problem matcher to find compile problems in the output. + "problemMatcher": "$tsc-watch", + "tasks": [ + { + "label": "npm", + "type": "shell", + "command": "npm", + "args": ["run", "compile", "--loglevel", "silent"], + "isBackground": true, + "problemMatcher": "$tsc-watch", + "group": { + "_id": "build", + "isDefault": false + } + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b7426e..d9bfe04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ # [4.4.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/4.4.0) + - **Bugfix:** Wrap test suites with single quotes - + # [v4.1.1](https://github.com/elonmallin/vscode-phpunit/releases/tag/v4.1.1) + - **Bugfix:** Don't stack up --color in the output command for each run. # [v4.1.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/v4.1.0) + - Handle `xml` files in `Run: Test` to enable running `` from `**phpunit.xml**` files. - Add `Run: Test Suite` to quick pick from all `**phpunit.xml**` files and then quick pick from all ``. - Add `phpunit.colors` setting to get colors by default `--colors=always`. Set to `null` or empty string to disable. @@ -14,10 +17,12 @@ - **Bugfix:** Extract filename for test with `path.basename` instead of regex to cover more cases. # [v4.0.1](https://github.com/elonmallin/vscode-phpunit/releases/tag/v4.0.1) + - **Bugfix:** Handle space in path for the filter arg of phpunit. - **Bugfix:** Use the `phpunit.php` config if the path is found. # [v4.0.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/v4.0.0) + - **BREAKING CHANGE** Updated vscode engine version required to latest 1.27.0. - Add color output and show failed tests in problems pane by running a task using a problem matcher. - Add config property `phpunit.docker.image` for choosing docker image for `DockerDriver`. @@ -25,39 +30,47 @@ - Add `phpunit.docker.container` to set running container to use for `DockerContainerDriver`. - Add `phpunit.command` config for running custom commands in place of php. Such as custom docker commands. - Add `phpunit.paths` to map paths for virtual environments. String replace with regex will be used for all paths in this config. Ex config: + ```json { - "/local/path": "/vitual/path", - "/second/local/path": "/second/virtual/path" + "/local/path": "/vitual/path", + "/second/local/path": "/second/virtual/path" } ``` # [v3.1.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/v3.1.0) + - Can now run php through docker. Will look for phpunit in all normal places (path, composer, phar). - Add Stop running phpunit command (kill process). - **Bugfix:** Prevent output window from stealing focus. - Update vscode, typescript and other packages. # [v3.0.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/v3.0.0) + - Now uses global php if not set at `phpunit.php` (previously `phpunit.execPath`) - `phpunit.execPath` still works for backwardscompatibility but is deprecated. - Now tries to find phpunit in the project folder (composers vendor dir and .phar files). - Will clear the output after each run (option: `clearOutputOnRun` default=true). # [v2.2.1](https://github.com/elonmallin/vscode-phpunit/releases/tag/v2.2.1) + - Add command `phpunit.RerunLastCommand`. Will run the last command again and can be bound to hotkey. # [v2.1.1](https://github.com/elonmallin/vscode-phpunit/releases/tag/v2.1.1) + - **Bugfix:** Function tests again allows `@test` docblocks and not just `test*` prefix. # [v2.1.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/v2.1.0) + - **Bugfix:** Run the instant tests reliably if the cursor is in the right place. Not every other try. - Add config option preferRunClassTestOverQuickPickWindow (default: false). Set to true to never show the quick pick window and just test the whole class if the cursor is on anything other than a function name. # [v2.0.1](https://github.com/elonmallin/vscode-phpunit/releases/tag/v2.0.1) + - **Bugfix:** Make sure the output channel is shown on test run. # [v2.0.0](https://github.com/elonmallin/vscode-phpunit/releases/tag/v2.0.0) + - This release shows the quick pick window to select a test when you run "PHPUnit Test" not directly on a function or class. If you have the cursor directly on the class or function name it will run instantly just like in previous releases. ![vscode-phpunit-quick-pick](images/vscode-phpunit-quick-pick.gif) diff --git a/LICENSE.md b/LICENSE.md index f5e5965..9ec7cb0 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,8 +1,7 @@ Copyright (c) 2016, Elon Mallin - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index bd0a069..c9b5a7e 100644 --- a/README.md +++ b/README.md @@ -4,29 +4,33 @@ [![test workflow](https://github.com/elonmallin/vscode-phpunit/actions/workflows/test.yml/badge.svg)](https://github.com/elonmallin/vscode-phpunit/actions/workflows/test.yml) [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/elonmallin/vscode-phpunit) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-round)](https://github.com/prettier/prettier) # PHPUnit for VSCode + This extension aims to need zero config and to be highly configurable. If you have `php` in environment path and `phpunit` installed with `composer` or anywhere in your workspace as `phpunit*.phar`, zero config is needed. It will even fallback to spinning up a self-removing `docker` container to try and run your tests if it can't find `php` on your machine. ![vscode-phpunit-demo](images/vscode-phpunit-demo-with-codelens.gif) ## Features - - Run tests with one **command** or **hotkey** based on **open file** (`*.php` or `phpunit.xml`) and **cursor position** - - "quick pick" window is shown where more complicated selections are needed - - Problems pane is populated with errors - - Color output - - Available commands: - - PHPUnit Test - - Tries to do the right thing (test `class/method` where cursor is or suite if file is `phpunit.xml`) - - PHPUnit Test Nearest - - PHPUnit Test Suite - - PHPUnit Test Directory - - PHPUnit Rerun Last Test - - PHPUnit Stop Running Tests + +- Run tests with one **command** or **hotkey** based on **open file** (`*.php` or `phpunit.xml`) and **cursor position** +- "quick pick" window is shown where more complicated selections are needed +- Problems pane is populated with errors +- Color output +- Available commands: +- PHPUnit Test + - Tries to do the right thing (test `class/method` where cursor is or suite if file is `phpunit.xml`) +- PHPUnit Test Nearest +- PHPUnit Test Suite +- PHPUnit Test Directory +- PHPUnit Rerun Last Test +- PHPUnit Stop Running Tests ## Manual setup -* Install [phpunit](https://phpunit.de/) in your workspace. -* Common config options: + +- Install [phpunit](https://phpunit.de/) in your workspace. +- Common config options: ```json5 { "phpunit.php": "path/to/php", // Skip to use php in env path @@ -43,13 +47,16 @@ This extension aims to need zero config and to be highly configurable. If you ha } } ``` + > **Zero config needed** if you have **php** or **docker** in you environment path and **phpunit** in your project (composer vendor dir or *.phar file). See the configuration section in [package.json](package.json) for all values and their descriptions (highly recommened if you need advanced functionality). ## Remote configs + For `docker`, `vagrant`, `laravel-homestead`, `WSL` or any other virtual/remote environment, **please consider the [Remote Development extension by Mircosoft](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)**. VSCode will run agains a remote directory and you can simply run your tests as you would locally. ### Manual ssh + ```json5 { "phpunit.ssh": "ssh root@localhost \"\"", // ssh command to connect to remote machine. @@ -59,11 +66,13 @@ For `docker`, `vagrant`, `laravel-homestead`, `WSL` or any other virtual/remote } } ``` + > `` is populated by the extension. The final command could then be something like `ssh root@localhost "php ./phpunit.phar -c phpunit.xml"` depending on your settings.

**Setup public/private keys** (passwords won't work):
- Windows powershell `ssh-keygen && cat $env:userprofile/.ssh/id_rsa.pub | ssh root@localhost 'cat >> .ssh/authorized_keys'`
- Linux bash `ssh-keygen && ssh-copy-id root@localhost`

**OpenSSH** (`ssh` and `ssh-keygen`) is available on windows since late 2018. It's easy to [install](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse) with powershell if it's not enabled. ### Manual docker container + ```json5 { "phpunit.docker.container": "container_name", // Skip to select from running containers @@ -74,6 +83,7 @@ For `docker`, `vagrant`, `laravel-homestead`, `WSL` or any other virtual/remote ``` ### Manual docker image + ```json5 { "phpunit.command": "docker run --rm -t -v ${pwd}:/app -w /app php:latest php", @@ -82,7 +92,9 @@ For `docker`, `vagrant`, `laravel-homestead`, `WSL` or any other virtual/remote } } ``` + ### Manual docker-compose service + ```json5 { "phpunit.command": "docker-compose run --rm service_name", @@ -93,28 +105,29 @@ For `docker`, `vagrant`, `laravel-homestead`, `WSL` or any other virtual/remote ``` # Examples + Run with (`Cmd+Shift+P` on OSX or `Ctrl+Shift+P` on Windows and Linux) and execute the `PHPUnit Test` command. -* **Test a function**: Place cursor on a function and run. +- **Test a function**: Place cursor on a function and run. ![vscode-phpunit-test-function](images/vscode-phpunit-test-function.gif) -* **Test a class**: Place cursor on class name and run. +- **Test a class**: Place cursor on class name and run. ![vscode-phpunit-test-class](images/vscode-phpunit-test-class.gif) -* **Pick test from a list**: Place cursor anywhere in class except on class name or on a function and run. +- **Pick test from a list**: Place cursor anywhere in class except on class name or on a function and run. ![vscode-phpunit-quick-pick](images/vscode-phpunit-quick-pick.gif) -* **Test everything according to --configuration**: Close editor window and run. +- **Test everything according to --configuration**: Close editor window and run. ![vscode-phpunit-test-all](images/vscode-phpunit-test-all.gif) -* **Test everything in a directory**: Open a file in the directory to test and run the `PHPUnit Test Directory` command. +- **Test everything in a directory**: Open a file in the directory to test and run the `PHPUnit Test Directory` command. ![vscode-phpunit-test-directory](images/vscode-phpunit-test-directory.gif) -* **Rerun last Test**: Run the `PHPUnit Rerun Last Test` command. +- **Rerun last Test**: Run the `PHPUnit Rerun Last Test` command. ## Keybinding example: diff --git a/package-lock.json b/package-lock.json index 030525c..c90e6ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,9 @@ "@vscode/test-electron": "^2.3.8", "cross-env": "^7.0.3", "eslint": "^8.55.0", + "eslint-config-prettier": "^9.1.0", "glob": "^10.3.10", + "husky": "^8.0.3", "mocha": "^10.2.0", "mocha-junit-reporter": "^2.2.1", "mocha-multi-reporters": "^1.5.1", @@ -1144,6 +1146,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -1615,6 +1629,21 @@ "node": ">= 6" } }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", diff --git a/package.json b/package.json index b714963..9371825 100644 --- a/package.json +++ b/package.json @@ -218,10 +218,12 @@ "clean": "rimraf ./out", "compile": "tsc -p ./", "lint": "eslint \"src/**/*.ts\"", + "format": "prettier --write .", "watch": "tsc -watch -p ./", "pretest": "npm run build", "test": "cross-env VSCODE_PHPUNIT_TEST=true node ./out/test/runTest.js", - "compile-php-project": "cd src/test/php-project && composer install && composer dump-autoload" + "compile-php-project": "cd src/test/php-project && composer install && composer dump-autoload", + "prepare": "husky install" }, "devDependencies": { "@types/command-exists": "^1.2.3", @@ -235,7 +237,9 @@ "@vscode/test-electron": "^2.3.8", "cross-env": "^7.0.3", "eslint": "^8.55.0", + "eslint-config-prettier": "^9.1.0", "glob": "^10.3.10", + "husky": "^8.0.0", "mocha": "^10.2.0", "mocha-junit-reporter": "^2.2.1", "mocha-multi-reporters": "^1.5.1", diff --git a/src/CodeLens/CodeLensFeature.ts b/src/CodeLens/CodeLensFeature.ts index 0361a51..73523e4 100644 --- a/src/CodeLens/CodeLensFeature.ts +++ b/src/CodeLens/CodeLensFeature.ts @@ -1,19 +1,23 @@ -import { ExtensionContext, workspace, languages, Disposable } from 'vscode'; -import { PhpCodeLensProvider } from './PhpCodeLensProvider'; -import { PhpunitXmlCodeLensProvider } from './PhpunitXmlCodeLensProvider'; +import { ExtensionContext, workspace, languages, Disposable } from "vscode"; +import { PhpCodeLensProvider } from "./PhpCodeLensProvider"; +import { PhpunitXmlCodeLensProvider } from "./PhpunitXmlCodeLensProvider"; let phpCodeLensProvider: Disposable | null; let phpunitXmlCodeLensProvider: Disposable | null; export function addCodeLensFeature(context: ExtensionContext) { - const codeLensEnabled = workspace.getConfiguration('phpunit').get('codeLens.enabled'); + const codeLensEnabled = workspace + .getConfiguration("phpunit") + .get("codeLens.enabled"); if (codeLensEnabled) { enableCodeLens(context); } workspace.onDidChangeConfiguration((event) => { - if (event.affectsConfiguration('phpunit.codeLens.enabled')) { - const codeLensEnabled = workspace.getConfiguration('phpunit').get('codeLens.enabled'); + if (event.affectsConfiguration("phpunit.codeLens.enabled")) { + const codeLensEnabled = workspace + .getConfiguration("phpunit") + .get("codeLens.enabled"); if (codeLensEnabled) { enableCodeLens(context); } else { @@ -28,17 +32,23 @@ function enableCodeLens(context: ExtensionContext) { return; } - phpCodeLensProvider = languages.registerCodeLensProvider({ - language: 'php', - scheme: 'file', - pattern: '**/test*/**/*.php' - }, new PhpCodeLensProvider()); + phpCodeLensProvider = languages.registerCodeLensProvider( + { + language: "php", + scheme: "file", + pattern: "**/test*/**/*.php", + }, + new PhpCodeLensProvider(), + ); - phpunitXmlCodeLensProvider = languages.registerCodeLensProvider({ - language: 'xml', - scheme: 'file', - pattern: '**/phpunit.xml*' - }, new PhpunitXmlCodeLensProvider()); + phpunitXmlCodeLensProvider = languages.registerCodeLensProvider( + { + language: "xml", + scheme: "file", + pattern: "**/phpunit.xml*", + }, + new PhpunitXmlCodeLensProvider(), + ); context.subscriptions.push(phpCodeLensProvider); context.subscriptions.push(phpunitXmlCodeLensProvider); @@ -49,12 +59,15 @@ function disableCodeLens(context: ExtensionContext) { return; } - const phpCodeLensProviderIdx = context.subscriptions.indexOf(phpCodeLensProvider); + const phpCodeLensProviderIdx = + context.subscriptions.indexOf(phpCodeLensProvider); context.subscriptions.splice(phpCodeLensProviderIdx, 1); phpCodeLensProvider.dispose(); phpCodeLensProvider = null; - - const phpunitXmlCodeLensProviderIdx = context.subscriptions.indexOf(phpunitXmlCodeLensProvider); + + const phpunitXmlCodeLensProviderIdx = context.subscriptions.indexOf( + phpunitXmlCodeLensProvider, + ); context.subscriptions.splice(phpunitXmlCodeLensProviderIdx, 1); phpunitXmlCodeLensProvider.dispose(); phpunitXmlCodeLensProvider = null; diff --git a/src/CodeLens/PhpCodeLensProvider.ts b/src/CodeLens/PhpCodeLensProvider.ts index cd600c1..70520df 100644 --- a/src/CodeLens/PhpCodeLensProvider.ts +++ b/src/CodeLens/PhpCodeLensProvider.ts @@ -1,19 +1,35 @@ -import { CodeLensProvider, CodeLens, CancellationToken, TextDocument, Range } from 'vscode'; -import { Class, CommentBlock, Engine, Identifier, Method, Namespace } from 'php-parser'; -import { PhpunitArgBuilder } from '../PhpunitCommand/PhpunitArgBuilder'; +import { + CodeLensProvider, + CodeLens, + CancellationToken, + TextDocument, + Range, +} from "vscode"; +import { + Class, + CommentBlock, + Engine, + Identifier, + Method, + Namespace, +} from "php-parser"; +import { PhpunitArgBuilder } from "../PhpunitCommand/PhpunitArgBuilder"; let lastDocumentText: string; let lastCodeLenses: Array = []; export class PhpCodeLensProvider implements CodeLensProvider { - public provideCodeLenses(document: TextDocument, token: CancellationToken): Array | Thenable> { + public provideCodeLenses( + document: TextDocument, + token: CancellationToken, + ): Array | Thenable> { if (document.getText() === lastDocumentText) { return lastCodeLenses; } const engine = new Engine({ ast: { - withPositions: true + withPositions: true, }, parser: { debug: false, @@ -34,15 +50,17 @@ export class PhpCodeLensProvider implements CodeLensProvider { const codeLenses: Array = []; for (const node of ast.children) { - if (node.kind === 'class') { - codeLenses.push(...this.parseClass(node as Class)); - } else if (node.kind === 'namespace') { - codeLenses.push(...this.parseNamespace(node as Namespace)); - } + if (node.kind === "class") { + codeLenses.push(...this.parseClass(node as Class)); + } else if (node.kind === "namespace") { + codeLenses.push(...this.parseNamespace(node as Namespace)); + } } for (const codeLens of codeLenses) { - (codeLens.command!.arguments![0] as PhpunitArgBuilder).addDirectoryOrFile(document.fileName); + (codeLens.command!.arguments![0] as PhpunitArgBuilder).addDirectoryOrFile( + document.fileName, + ); } lastDocumentText = document.getText(); @@ -60,7 +78,7 @@ export class PhpCodeLensProvider implements CodeLensProvider { const codeLenses: Array = []; for (const child of node.children) { - if (child.kind === 'class') { + if (child.kind === "class") { codeLenses.push(...this.parseClass(child as Class)); } } @@ -72,28 +90,35 @@ export class PhpCodeLensProvider implements CodeLensProvider { const codeLenses = []; for (const child of node.body) { - if (child.kind !== 'method') { - continue; - } - - const codeLens = this.parseMethod(child as Method); - if (codeLens) { - codeLenses.push(codeLens); - } + if (child.kind !== "method") { + continue; + } + + const codeLens = this.parseMethod(child as Method); + if (codeLens) { + codeLenses.push(codeLens); + } } if (codeLenses.length > 0) { - const classCodeLensRange = new Range(node.loc!.start.line - 1, 0, node.loc!.start.line - 1, 0); - const className = typeof node.name === 'string' ? node.name : (node.name as Identifier).name; - - codeLenses.push(new CodeLens(classCodeLensRange, { - command: 'phpunit.Test', - title: "Run tests", - arguments: [ - new PhpunitArgBuilder() - .withFilter(className) - ], - })); + const classCodeLensRange = new Range( + node.loc!.start.line - 1, + 0, + node.loc!.start.line - 1, + 0, + ); + const className = + typeof node.name === "string" + ? node.name + : (node.name as Identifier).name; + + codeLenses.push( + new CodeLens(classCodeLensRange, { + command: "phpunit.Test", + title: "Run tests", + arguments: [new PhpunitArgBuilder().withFilter(className)], + }), + ); } return codeLenses; @@ -102,24 +127,32 @@ export class PhpCodeLensProvider implements CodeLensProvider { private parseMethod(node: Method): CodeLens | null { const leadingComments = node.leadingComments || []; const hasTestAnnotation = leadingComments.find((comment: CommentBlock) => { - return comment.kind === 'commentblock' && comment.value.indexOf('* @test') != -1; + return ( + comment.kind === "commentblock" && + comment.value.indexOf("* @test") != -1 + ); }); - const methodName = typeof node.name === 'string' ? node.name : (node.name as Identifier).name; + const methodName = + typeof node.name === "string" + ? node.name + : (node.name as Identifier).name; - if (!methodName.startsWith('test') && !hasTestAnnotation) { - return null; + if (!methodName.startsWith("test") && !hasTestAnnotation) { + return null; } - const codeLensRange = new Range(node.loc!.start.line - 1, 0, node.loc!.start.line - 1, 0); + const codeLensRange = new Range( + node.loc!.start.line - 1, + 0, + node.loc!.start.line - 1, + 0, + ); return new CodeLens(codeLensRange, { - command: 'phpunit.Test', - title: 'Run test', - arguments: [ - new PhpunitArgBuilder() - .withFilter(methodName) - ], + command: "phpunit.Test", + title: "Run test", + arguments: [new PhpunitArgBuilder().withFilter(methodName)], }); } } diff --git a/src/CodeLens/PhpunitXmlCodeLensProvider.ts b/src/CodeLens/PhpunitXmlCodeLensProvider.ts index f08b94e..83e8a3e 100644 --- a/src/CodeLens/PhpunitXmlCodeLensProvider.ts +++ b/src/CodeLens/PhpunitXmlCodeLensProvider.ts @@ -1,13 +1,22 @@ -import { CodeLensProvider, CodeLens, CancellationToken, TextDocument, Range } from 'vscode'; -import { parse, DocumentCstNode } from '@xml-tools/parser'; -import { buildAst, XMLElement, } from '@xml-tools/ast'; -import { PhpunitArgBuilder } from '../PhpunitCommand/PhpunitArgBuilder'; +import { + CodeLensProvider, + CodeLens, + CancellationToken, + TextDocument, + Range, +} from "vscode"; +import { parse, DocumentCstNode } from "@xml-tools/parser"; +import { buildAst, XMLElement } from "@xml-tools/ast"; +import { PhpunitArgBuilder } from "../PhpunitCommand/PhpunitArgBuilder"; let lastDocumentText: string; let lastCodeLenses: Array = []; export class PhpunitXmlCodeLensProvider implements CodeLensProvider { - public provideCodeLenses(document: TextDocument, token: CancellationToken): Array | Thenable> { + public provideCodeLenses( + document: TextDocument, + token: CancellationToken, + ): Array | Thenable> { if (!/phpunit\.xml(\.dist)?/.test(document.fileName)) { return []; } @@ -22,9 +31,9 @@ export class PhpunitXmlCodeLensProvider implements CodeLensProvider { const codeLenses: Array = []; for (const node of ast.rootElement!.subElements) { - if (node.name === 'testsuites') { - codeLenses.push(...this.parseTestSuites(node, document.fileName)); - } + if (node.name === "testsuites") { + codeLenses.push(...this.parseTestSuites(node, document.fileName)); + } } lastDocumentText = document.getText(); @@ -42,39 +51,45 @@ export class PhpunitXmlCodeLensProvider implements CodeLensProvider { const codeLenses: Array = []; for (const child of node.subElements) { - if (child.name === 'testsuite') { + if (child.name === "testsuite") { codeLenses.push(this.parseTestSuite(child, fileName)); } } if (codeLenses.length > 0) { - const codeLensRange = new Range(node.position.startLine - 1, 0, node.position.startLine - 1, 0); - - codeLenses.push(new CodeLens(codeLensRange, { - command: 'phpunit.Test', - title: 'Run tests', - arguments: [ - new PhpunitArgBuilder() - .withConfig(fileName) - ] - })); + const codeLensRange = new Range( + node.position.startLine - 1, + 0, + node.position.startLine - 1, + 0, + ); + + codeLenses.push( + new CodeLens(codeLensRange, { + command: "phpunit.Test", + title: "Run tests", + arguments: [new PhpunitArgBuilder().withConfig(fileName)], + }), + ); } return codeLenses; } private parseTestSuite(node: XMLElement, fileName: string): CodeLens { - const codeLensRange = new Range(node.position.startLine - 1, 0, node.position.startLine - 1, 0); - const name = node.attributes.find((attribute) => attribute.key === 'name')!.value!; + const codeLensRange = new Range( + node.position.startLine - 1, + 0, + node.position.startLine - 1, + 0, + ); + const name = node.attributes.find((attribute) => attribute.key === "name")! + .value!; return new CodeLens(codeLensRange, { - command: 'phpunit.Test', - title: 'Run test', - arguments: [ - new PhpunitArgBuilder() - .withConfig(fileName) - .addSuite(name) - ] + command: "phpunit.Test", + title: "Run test", + arguments: [new PhpunitArgBuilder().withConfig(fileName).addSuite(name)], }); } } diff --git a/src/DockerCmdUtils.ts b/src/DockerCmdUtils.ts index bd4ea72..6a06530 100644 --- a/src/DockerCmdUtils.ts +++ b/src/DockerCmdUtils.ts @@ -10,12 +10,12 @@ const docker = { await nrc.run("docker container ls", { onData: (data: any) => { output += data; - } + }, }); return output .split("\n") - .filter(r => r) + .filter((r) => r) .reduce((acc, next, idx, arr) => { if (idx === 0) { return acc; // First line is column names. @@ -26,14 +26,15 @@ const docker = { const container = {}; for (let i = 0; i < names.length; ++i) { - (container as any)[names[i]] = values[Math.min(i, values.length - 1)]; + (container as any)[names[i]] = + values[Math.min(i, values.length - 1)]; } acc.push(container); return acc; }, new Array()); - } - } + }, + }, }; export default docker; diff --git a/src/Drivers/CommandDriver.ts b/src/Drivers/CommandDriver.ts index 21a92db..b9cbea5 100644 --- a/src/Drivers/CommandDriver.ts +++ b/src/Drivers/CommandDriver.ts @@ -16,7 +16,7 @@ export default class Command implements IPhpUnitDriver { command: command, exec: await this.command(), args: args, - problemMatcher: "$phpunit-app" + problemMatcher: "$phpunit-app", }; } diff --git a/src/Drivers/ComposerDriver.ts b/src/Drivers/ComposerDriver.ts index 44f98e8..d07cfd3 100644 --- a/src/Drivers/ComposerDriver.ts +++ b/src/Drivers/ComposerDriver.ts @@ -63,12 +63,12 @@ export default class Composer implements IPhpUnitDriver { ? await vscode.workspace.findFiles( "**/vendor/phpunit/phpunit/phpunit", "**/node_modules/**", - 1 + 1, ) : await vscode.workspace.findFiles( "**/vendor/bin/phpunit", "**/node_modules/**", - 1 + 1, ); return (this.phpUnitPathCache = @@ -79,7 +79,7 @@ export default class Composer implements IPhpUnitDriver { const phpUnitPath = config.get("phpunit"); if (phpUnitPath) { this.phpUnitPathCache = await new Promise((resolve, reject) => { - fs.exists(phpUnitPath, exists => { + fs.exists(phpUnitPath, (exists) => { if (exists) { resolve(phpUnitPath); } else { diff --git a/src/Drivers/DockerContainerDriver.ts b/src/Drivers/DockerContainerDriver.ts index e815160..ec02544 100644 --- a/src/Drivers/DockerContainerDriver.ts +++ b/src/Drivers/DockerContainerDriver.ts @@ -16,7 +16,7 @@ export default class DockerContainer implements IPhpUnitDriver { "-t", this.dockerContainer, "php", - await this.phpUnitPath() + await this.phpUnitPath(), ].concat(args); const command = `docker ${params.join(" ").replace(/\\/gi, "/")}`; @@ -25,7 +25,7 @@ export default class DockerContainer implements IPhpUnitDriver { command: command, exec: "docker", args: params as string[], - problemMatcher: "$phpunit-app" + problemMatcher: "$phpunit-app", }; } @@ -40,16 +40,16 @@ export default class DockerContainer implements IPhpUnitDriver { if (containers.length > 0) { this.dockerContainer = await vscode.window.showQuickPick( - containers.map(r => r.NAMES), + containers.map((r) => r.NAMES), { placeHolder: - "Pick a running docker container to run phpunit test in..." - } + "Pick a running docker container to run phpunit test in...", + }, ); if (!this.dockerContainer) { vscode.window.showInformationMessage( - `No docker container selected. Skipping ${this.name} driver.` + `No docker container selected. Skipping ${this.name} driver.`, ); } } diff --git a/src/Drivers/DockerDriver.ts b/src/Drivers/DockerDriver.ts index 97cd5cc..759884f 100644 --- a/src/Drivers/DockerDriver.ts +++ b/src/Drivers/DockerDriver.ts @@ -23,13 +23,16 @@ export default class Docker implements IPhpUnitDriver { "/app", dockerImage, "php", - await this.phpUnitPath() + await this.phpUnitPath(), ] .concat(args) .join(" ") .replace( - new RegExp(escapeStringRegexp(vscode.workspace.workspaceFolders![0].uri.fsPath), "ig"), - "/app" + new RegExp( + escapeStringRegexp(vscode.workspace.workspaceFolders![0].uri.fsPath), + "ig", + ), + "/app", ) .replace(/\\/gi, "/") .split(" "); @@ -40,7 +43,7 @@ export default class Docker implements IPhpUnitDriver { command: command, exec: "docker", args: args, - problemMatcher: "$phpunit-app" + problemMatcher: "$phpunit-app", }; } diff --git a/src/Drivers/GlobalPhpUnitDriver.ts b/src/Drivers/GlobalPhpUnitDriver.ts index 6ace433..c96d5c3 100644 --- a/src/Drivers/GlobalPhpUnitDriver.ts +++ b/src/Drivers/GlobalPhpUnitDriver.ts @@ -15,7 +15,7 @@ export default class GlobalPhpUnit implements IPhpUnitDriver { return { command: command, exec: execPath, - args: args + args: args, }; } diff --git a/src/Drivers/PathDriver.ts b/src/Drivers/PathDriver.ts index 5af6e3a..2a24673 100644 --- a/src/Drivers/PathDriver.ts +++ b/src/Drivers/PathDriver.ts @@ -65,16 +65,16 @@ export default class Path implements IPhpUnitDriver { ? undefined : await new Promise((resolve, reject) => { try { - fs.exists(phpUnitPath, exists => { + fs.exists(phpUnitPath, (exists) => { if (exists) { this.phpUnitPathCache = phpUnitPath; resolve(this.phpUnitPathCache); } else { const absPhpUnitPath = path.join( vscode.workspace.workspaceFolders![0].uri.fsPath, - phpUnitPath + phpUnitPath, ); - fs.exists(absPhpUnitPath, absExists => { + fs.exists(absPhpUnitPath, (absExists) => { if (absExists) { this.phpUnitPathCache = absPhpUnitPath; resolve(this.phpUnitPathCache); diff --git a/src/Drivers/PharDriver.ts b/src/Drivers/PharDriver.ts index e2bfc37..a2286fb 100644 --- a/src/Drivers/PharDriver.ts +++ b/src/Drivers/PharDriver.ts @@ -20,7 +20,7 @@ export default class Phar implements IPhpUnitDriver { return { command: command, exec: execPath, - args: args + args: args, }; } @@ -44,9 +44,9 @@ export default class Phar implements IPhpUnitDriver { `${await this.phpPath()} -r "echo extension_loaded('phar');"`, (err, stdout, stderr) => { resolve(stdout === "1"); - } + }, ); - } + }, )); } @@ -77,7 +77,7 @@ export default class Phar implements IPhpUnitDriver { const uris = await vscode.workspace.findFiles( "**/phpunit*.phar", "**/node_modules/**", - 1 + 1, ); this.phpUnitPharPathCache = uris && uris.length > 0 ? uris[0].fsPath : undefined; @@ -90,14 +90,14 @@ export default class Phar implements IPhpUnitDriver { if (phpUnitPath && phpUnitPath.endsWith(".phar")) { this.phpUnitPharPathCache = await new Promise( (resolve, reject) => { - fs.exists(phpUnitPath, exists => { + fs.exists(phpUnitPath, (exists) => { if (exists) { resolve(phpUnitPath); } else { reject(); } }); - } + }, ).catch(findInWorkspace); } else { this.phpUnitPharPathCache = await findInWorkspace(); diff --git a/src/Drivers/PhpUnitDrivers.ts b/src/Drivers/PhpUnitDrivers.ts index 020e2e4..73e3b77 100644 --- a/src/Drivers/PhpUnitDrivers.ts +++ b/src/Drivers/PhpUnitDrivers.ts @@ -19,5 +19,5 @@ export default { Legacy, Path, Phar, - Ssh + Ssh, }; diff --git a/src/Drivers/PhpUnitResolver.ts b/src/Drivers/PhpUnitResolver.ts index 5ae7ade..c75cd77 100644 --- a/src/Drivers/PhpUnitResolver.ts +++ b/src/Drivers/PhpUnitResolver.ts @@ -27,7 +27,7 @@ const getDrivers = (order?: string[]): IPhpUnitDriver[] => { new Path(), new Composer(), new Phar(), - new GlobalPhpUnit() + new GlobalPhpUnit(), ]; function arrayUnique(array: any[]) { @@ -42,7 +42,7 @@ const getDrivers = (order?: string[]): IPhpUnitDriver[] => { return a; } - order = arrayUnique((order || []).concat(drivers.map(d => d.name))); + order = arrayUnique((order || []).concat(drivers.map((d) => d.name))); const sortedDrivers = drivers.sort((a, b) => { return order!.indexOf(a.name) - order!.indexOf(b.name); diff --git a/src/Drivers/SshDriver.ts b/src/Drivers/SshDriver.ts index 47be45d..ef42e1e 100644 --- a/src/Drivers/SshDriver.ts +++ b/src/Drivers/SshDriver.ts @@ -10,7 +10,9 @@ export default class Ssh implements IPhpUnitDriver { private ssh?: string; public async run(args: string[]): Promise { - const argsString = `${this.phpPathCache} ${this.phpUnitPathCache} ${args.join(" ")}`; + const argsString = `${this.phpPathCache} ${ + this.phpUnitPathCache + } ${args.join(" ")}`; return { command: `${this.ssh!.replace("", argsString)}`, diff --git a/src/PhpParser/TestDiffParser.ts b/src/PhpParser/TestDiffParser.ts index bef4309..01df2dd 100644 --- a/src/PhpParser/TestDiffParser.ts +++ b/src/PhpParser/TestDiffParser.ts @@ -2,24 +2,26 @@ export class TestDiffParser { constructor( public readonly message: string, public readonly expected: string, - public readonly actual: string) { - - } + public readonly actual: string, + ) {} } export function getTestFailedDiff(output: string): TestDiffParser { const [message] = /^Failed asserting that .*$/im.exec(output)!; - if (/--- Expected/ig.test(output)) { - const expectedMatches = output.match(/^- .*$/igm); - const expected = expectedMatches!.join('\n'); + if (/--- Expected/gi.test(output)) { + const expectedMatches = output.match(/^- .*$/gim); + const expected = expectedMatches!.join("\n"); - const actualMatches = output.match(/^\+ .*$/igm); - const actual = actualMatches!.join('\n'); + const actualMatches = output.match(/^\+ .*$/gim); + const actual = actualMatches!.join("\n"); return new TestDiffParser(message, expected, actual); } else { - const [, expected, ,actual] = /^Failed asserting that (.*) (is|are|matches expected) (.*)\.$/im.exec(output)!; + const [, expected, , actual] = + /^Failed asserting that (.*) (is|are|matches expected) (.*)\.$/im.exec( + output, + )!; return new TestDiffParser(message, expected, actual); } diff --git a/src/PhpunitCommand/PhpunitArgBuilder.ts b/src/PhpunitCommand/PhpunitArgBuilder.ts index c38ac4f..8da7bea 100644 --- a/src/PhpunitCommand/PhpunitArgBuilder.ts +++ b/src/PhpunitCommand/PhpunitArgBuilder.ts @@ -19,13 +19,13 @@ export class PhpunitArgBuilder { public addSuite(suiteName: string): PhpunitArgBuilder { this.suites.push(suiteName); - + return this; } public addSuites(suiteNames: Array): PhpunitArgBuilder { this.suites.push(...suiteNames); - + return this; } @@ -53,7 +53,7 @@ export class PhpunitArgBuilder { return this; } - public withColors(color: 'never' | 'auto' | 'always'): PhpunitArgBuilder { + public withColors(color: "never" | "auto" | "always"): PhpunitArgBuilder { this.color = color; return this; @@ -65,7 +65,10 @@ export class PhpunitArgBuilder { return this; } - public withPathMappings(pathMappings: { [key: string]: string }, workspaceFolder: string): PhpunitArgBuilder { + public withPathMappings( + pathMappings: { [key: string]: string }, + workspaceFolder: string, + ): PhpunitArgBuilder { this.pathMappings = pathMappings; this.workspaceFolder = workspaceFolder; @@ -74,15 +77,14 @@ export class PhpunitArgBuilder { public buildArgs(): Array { let args = [ - ...(this.configFile ? ['--configuration', this.configFile] : []), + ...(this.configFile ? ["--configuration", this.configFile] : []), ...(this.color ? [`--colors=${this.color}`] : []), - ...(this.suites.length > 0 ? ['--testsuite', this.suites.join(',')] : []), - ...(this.filter ? ['--filter', `'${this.filter}'`] : []), - ...(this.groups.length > 0 ? ['--group', this.groups.join(',')] : []), + ...(this.suites.length > 0 ? ["--testsuite", this.suites.join(",")] : []), + ...(this.filter ? ["--filter", `'${this.filter}'`] : []), + ...(this.groups.length > 0 ? ["--group", this.groups.join(",")] : []), ...this.args, ...this.directoryOrFiles, - ] - .filter(part => part); + ].filter((part) => part); if (this.pathMappings) { for (const key of Object.keys(this.pathMappings)) { @@ -91,14 +93,19 @@ export class PhpunitArgBuilder { .replace(/\\/gi, "/"); const remotePath = this.pathMappings[key]; - args = args.map(arg => arg.replace(new RegExp(escapeStringRegexp(localPath), "ig"), remotePath)); + args = args.map((arg) => + arg.replace( + new RegExp(escapeStringRegexp(localPath), "ig"), + remotePath, + ), + ); } } - return args.filter(part => part); + return args.filter((part) => part); } public build(): string { - return this.buildArgs().join(' '); + return this.buildArgs().join(" "); } } diff --git a/src/TestProvider/TestCases/TestCaseNode.ts b/src/TestProvider/TestCases/TestCaseNode.ts index a227a19..74e0562 100644 --- a/src/TestProvider/TestCases/TestCaseNode.ts +++ b/src/TestProvider/TestCases/TestCaseNode.ts @@ -1,6 +1,6 @@ import { Range } from "vscode"; -export type TestCaseNodeKind = 'namespace' | 'class' | 'method'; +export type TestCaseNodeKind = "namespace" | "class" | "method"; export class TestCaseNode { constructor( diff --git a/src/TestProvider/TestCases/TestCaseRepository.ts b/src/TestProvider/TestCases/TestCaseRepository.ts index 672d098..b1b81a4 100644 --- a/src/TestProvider/TestCases/TestCaseRepository.ts +++ b/src/TestProvider/TestCases/TestCaseRepository.ts @@ -1,4 +1,11 @@ -import { Range, TestController, TestItem, TestItemCollection, Uri, workspace } from "vscode"; +import { + Range, + TestController, + TestItem, + TestItemCollection, + Uri, + workspace, +} from "vscode"; import * as path from "path"; import { TestFileParser } from "../TestFileParser"; import { TestClass } from "./TestClass"; @@ -11,48 +18,78 @@ import { ITestCase } from "./ITestCase"; export const testData = new WeakMap(); export function gatherTestItems(collection: TestItemCollection) { - const items: TestItem[] = []; - collection.forEach(item => items.push(item)); + const items: TestItem[] = []; + collection.forEach((item) => items.push(item)); - return items; + return items; } -async function getOrCreateFromTestCaseNodes(controller: TestController, uri: Uri, testCaseNodes: Array, parentItemCollecton: TestItemCollection): Promise { +async function getOrCreateFromTestCaseNodes( + controller: TestController, + uri: Uri, + testCaseNodes: Array, + parentItemCollecton: TestItemCollection, +): Promise { for (const testCaseNode of testCaseNodes) { - if (testCaseNode.kind === 'namespace') { + if (testCaseNode.kind === "namespace") { if (testCaseNode.children?.length > 0) { - await getOrCreateFromTestCaseNodes(controller, uri, testCaseNode.children, parentItemCollecton); + await getOrCreateFromTestCaseNodes( + controller, + uri, + testCaseNode.children, + parentItemCollecton, + ); } - } - else if (testCaseNode.kind === 'class') { - const testCase = new TestClass(uri.fsPath, testCaseNode.name, testCaseNode.range, testCaseNode.parent?.name); + } else if (testCaseNode.kind === "class") { + const testCase = new TestClass( + uri.fsPath, + testCaseNode.name, + testCaseNode.range, + testCaseNode.parent?.name, + ); let testItem = parentItemCollecton.get(testCase.getId()); if (!testItem) { - testItem = controller.createTestItem(testCase.getId(), testCase.getLabel(), uri); + testItem = controller.createTestItem( + testCase.getId(), + testCase.getLabel(), + uri, + ); testData.set(testItem, testCase); testItem.range = testCase.getRange(); - testItem.description = 'class'; + testItem.description = "class"; parentItemCollecton.add(testItem); - } - else { + } else { testItem.range = testCase.getRange(); } if (testCaseNode.children?.length > 0) { - await getOrCreateFromTestCaseNodes(controller, uri, testCaseNode.children, testItem.children); + await getOrCreateFromTestCaseNodes( + controller, + uri, + testCaseNode.children, + testItem.children, + ); } - } - else if (testCaseNode.kind === 'method') { - const testCase = new TestMethod(uri.fsPath, testCaseNode.name, testCaseNode.range, testCaseNode.parent?.name, testCaseNode.parent?.parent?.name); + } else if (testCaseNode.kind === "method") { + const testCase = new TestMethod( + uri.fsPath, + testCaseNode.name, + testCaseNode.range, + testCaseNode.parent?.name, + testCaseNode.parent?.parent?.name, + ); let testItem = parentItemCollecton.get(testCase.getId()); if (!testItem) { - testItem = controller.createTestItem(testCase.getId(), testCase.getLabel(), uri); + testItem = controller.createTestItem( + testCase.getId(), + testCase.getLabel(), + uri, + ); testData.set(testItem, testCase); - testItem.description = 'method'; + testItem.description = "method"; testItem.range = testCase.getRange(); parentItemCollecton.add(testItem); - } - else { + } else { testItem.range = testCase.getRange(); } } @@ -61,8 +98,12 @@ async function getOrCreateFromTestCaseNodes(controller: TestController, uri: Uri return gatherTestItems(parentItemCollecton); } -export async function deleteFromUri(controller: TestController, testItemCollection: TestItemCollection, uri: Uri) { - if (uri.scheme !== 'file') { +export async function deleteFromUri( + controller: TestController, + testItemCollection: TestItemCollection, + uri: Uri, +) { + if (uri.scheme !== "file") { return; } @@ -73,7 +114,7 @@ export async function deleteFromUri(controller: TestController, testItemCollecti deleteFromTestData(item); } - testItemCollection.forEach(item => { + testItemCollection.forEach((item) => { if (item.children) { deleteFromUri(controller, item.children, uri); } @@ -84,12 +125,16 @@ function deleteFromTestData(testItem: TestItem) { testData.delete(testItem); if (testItem.children) { - testItem.children.forEach(child => deleteFromTestData(child)); + testItem.children.forEach((child) => deleteFromTestData(child)); } } -export async function createOrUpdateFromPath(controller: TestController, filePath: string, commonDirectory: string) { - const pathParts = filePath.replace(commonDirectory, '').split(/[/\\]+/i); +export async function createOrUpdateFromPath( + controller: TestController, + filePath: string, + commonDirectory: string, +) { + const pathParts = filePath.replace(commonDirectory, "").split(/[/\\]+/i); const paths: string[] = []; let currentPath = commonDirectory; for (const part of pathParts) { @@ -100,7 +145,11 @@ export async function createOrUpdateFromPath(controller: TestController, filePat createOrUpdateItem(controller, controller.items, paths); } -async function createOrUpdateItem(controller: TestController, parentItemCollecton: TestItemCollection, paths: string[]) { +async function createOrUpdateItem( + controller: TestController, + parentItemCollecton: TestItemCollection, + paths: string[], +) { const currentPath = paths.shift(); if (!currentPath) { return; @@ -113,33 +162,45 @@ async function createOrUpdateItem(controller: TestController, parentItemCollecto return; } - if (currentPath.endsWith('.php')) { + if (currentPath.endsWith(".php")) { const testCase = new TestFile(currentPath); - const testItem = controller.createTestItem(testCase.getId(), testCase.getLabel(), pathToUri(currentPath)); + const testItem = controller.createTestItem( + testCase.getId(), + testCase.getLabel(), + pathToUri(currentPath), + ); testItem.canResolveChildren = true; - + parentItemCollecton.add(testItem); testData.set(testItem, testCase); - + const currentUri = pathToUri(currentPath); const rawContent = await workspace.fs.readFile(currentUri); - const content = new TextDecoder('utf-8').decode(rawContent); + const content = new TextDecoder("utf-8").decode(rawContent); const testCaseNodes = new TestFileParser().parse(content, currentUri); - await getOrCreateFromTestCaseNodes(controller, currentUri, testCaseNodes, testItem.children); - } - else { + await getOrCreateFromTestCaseNodes( + controller, + currentUri, + testCaseNodes, + testItem.children, + ); + } else { const testCase = new TestDirectory(currentPath); - const testItem = controller.createTestItem(testCase.getId(), testCase.getLabel(), pathToUri(currentPath)); + const testItem = controller.createTestItem( + testCase.getId(), + testCase.getLabel(), + pathToUri(currentPath), + ); testItem.canResolveChildren = true; - + parentItemCollecton.add(testItem); testData.set(testItem, testCase); - + createOrUpdateItem(controller, testItem.children, paths); } } function pathToUri(path: string) { - return Uri.parse(`file:///${path.replace(/\\/g, '/').replace(':', '%3A')}`); + return Uri.parse(`file:///${path.replace(/\\/g, "/").replace(":", "%3A")}`); } diff --git a/src/TestProvider/TestCases/TestClass.ts b/src/TestProvider/TestCases/TestClass.ts index 2e66d8e..798c2f1 100644 --- a/src/TestProvider/TestCases/TestClass.ts +++ b/src/TestProvider/TestCases/TestClass.ts @@ -1,30 +1,39 @@ -import { Location, Position, Range, TestItem, TestMessage, TestRun } from "vscode"; +import { + Location, + Position, + Range, + TestItem, + TestMessage, + TestRun, +} from "vscode"; import { ITestCase } from "./ITestCase"; import { testData } from "./TestCaseRepository"; export class TestClass implements ITestCase { - constructor( - private readonly fileName: string, + constructor( + private readonly fileName: string, private readonly className: string, public readonly range: Range, public readonly namespace: string | undefined = undefined, - public isResolved: boolean = true - ) { } + public isResolved: boolean = true, + ) {} - getId() { - return `${this.fileName}${this.namespace ? `/${this.namespace}` : ''}/${this.className}`; - } + getId() { + return `${this.fileName}${this.namespace ? `/${this.namespace}` : ""}/${ + this.className + }`; + } - getLabel() { - return this.className; - } + getLabel() { + return this.className; + } getRange() { return this.range; } - async run(item: TestItem, options: TestRun): Promise { - const start = Date.now(); + async run(item: TestItem, options: TestRun): Promise { + const start = Date.now(); const testCasePromises: Promise[] = []; for (const [id, child] of item.children) { @@ -39,14 +48,13 @@ export class TestClass implements ITestCase { options.passed(item, duration); return true; - } - catch (e) { + } catch (e) { const duration = Date.now() - start; - const message = new TestMessage('Failed'); + const message = new TestMessage("Failed"); message.location = new Location(item.uri!, new Position(0, 0)); - options.failed(item, new TestMessage('Failed'), duration); + options.failed(item, new TestMessage("Failed"), duration); return false; } - } + } } diff --git a/src/TestProvider/TestCases/TestDirectory.ts b/src/TestProvider/TestCases/TestDirectory.ts index 8ecd818..13dc8a1 100644 --- a/src/TestProvider/TestCases/TestDirectory.ts +++ b/src/TestProvider/TestCases/TestDirectory.ts @@ -6,14 +6,14 @@ import { testData } from "./TestCaseRepository"; export class TestDirectory implements ITestCase { private readonly testItem: TestItem | undefined; - constructor( - private readonly directory: string, - public isResolved: boolean = false - ) { } + constructor( + private readonly directory: string, + public isResolved: boolean = false, + ) {} - getId() { - return `${this.directory}`; - } + getId() { + return `${this.directory}`; + } getLabel() { return path.basename(this.directory); @@ -27,8 +27,8 @@ export class TestDirectory implements ITestCase { return this.testItem; } - async run(item: TestItem, options: TestRun): Promise { - const start = Date.now(); + async run(item: TestItem, options: TestRun): Promise { + const start = Date.now(); const testCasePromises: Promise[] = []; for (const [id, child] of item.children) { @@ -43,14 +43,13 @@ export class TestDirectory implements ITestCase { options.passed(item, duration); return true; - } - catch (e) { + } catch (e) { const duration = Date.now() - start; - const message = new TestMessage('Failed'); + const message = new TestMessage("Failed"); message.location = new Location(item.uri!, new Position(0, 0)); - options.failed(item, new TestMessage('Failed'), duration); + options.failed(item, new TestMessage("Failed"), duration); return false; } - } + } } diff --git a/src/TestProvider/TestCases/TestFile.ts b/src/TestProvider/TestCases/TestFile.ts index a60a9c2..566cafb 100644 --- a/src/TestProvider/TestCases/TestFile.ts +++ b/src/TestProvider/TestCases/TestFile.ts @@ -4,25 +4,25 @@ import path = require("path"); import { testData } from "./TestCaseRepository"; export class TestFile implements ITestCase { - constructor( - private readonly fileName: string, - public isResolved: boolean = true - ) { } + constructor( + private readonly fileName: string, + public isResolved: boolean = true, + ) {} - getId() { - return `${this.fileName}`; - } + getId() { + return `${this.fileName}`; + } - getLabel() { - return path.basename(this.fileName); - } + getLabel() { + return path.basename(this.fileName); + } getRange() { return undefined; } - async run(item: TestItem, options: TestRun): Promise { - const start = Date.now(); + async run(item: TestItem, options: TestRun): Promise { + const start = Date.now(); const testCasePromises: Promise[] = []; for (const [id, child] of item.children) { @@ -37,14 +37,13 @@ export class TestFile implements ITestCase { options.passed(item, duration); return true; - } - catch (e) { + } catch (e) { const duration = Date.now() - start; - const message = new TestMessage('Failed'); + const message = new TestMessage("Failed"); message.location = new Location(item.uri!, new Position(0, 0)); - options.failed(item, new TestMessage('Failed'), duration); + options.failed(item, new TestMessage("Failed"), duration); return false; } - } + } } diff --git a/src/TestProvider/TestCases/TestMethod.ts b/src/TestProvider/TestCases/TestMethod.ts index 21278b5..8e4c40a 100644 --- a/src/TestProvider/TestCases/TestMethod.ts +++ b/src/TestProvider/TestCases/TestMethod.ts @@ -6,54 +6,62 @@ import { getTestFailedDiff } from "../../PhpParser/TestDiffParser"; import { ITestCase } from "./ITestCase"; export class TestMethod implements ITestCase { - constructor( - private readonly fileName: string, + constructor( + private readonly fileName: string, private readonly method: string, public readonly range: Range, public readonly className: string | undefined = undefined, public readonly namespace: string | undefined = undefined, - public isResolved: boolean = true - ) { } + public isResolved: boolean = true, + ) {} - getId() { - return `${this.fileName}${this.namespace ? `/${this.namespace}` : ''}${this.className ? `/${this.className}` : ''}/${this.method}`; - } + getId() { + return `${this.fileName}${this.namespace ? `/${this.namespace}` : ""}${ + this.className ? `/${this.className}` : "" + }/${this.method}`; + } - getLabel() { - return this.method; - } + getLabel() { + return this.method; + } getRange() { return this.range; } - async run(item: TestItem, options: TestRun): Promise { - const start = Date.now(); + async run(item: TestItem, options: TestRun): Promise { + const start = Date.now(); const argBuilder = new PhpunitArgBuilder(); argBuilder.addDirectoryOrFile(this.fileName); argBuilder.withFilter(this.method); - const { status, stdout, stderr, error } = await PHPUnitTestRunner.runArgs(argBuilder, true) as SpawnSyncReturns; + const { status, stdout, stderr, error } = (await PHPUnitTestRunner.runArgs( + argBuilder, + true, + )) as SpawnSyncReturns; - const duration = Date.now() - start; + const duration = Date.now() - start; - if (status === 0) { - options.passed(item, duration); + if (status === 0) { + options.passed(item, duration); return true; - } + } try { const testDiff = getTestFailedDiff(stdout); - const message = TestMessage.diff(testDiff.message, testDiff.expected, testDiff.actual); + const message = TestMessage.diff( + testDiff.message, + testDiff.expected, + testDiff.actual, + ); message.location = new Location(item.uri!, item.range!); - + options.failed(item, message, duration); - + return false; - } - catch (e: any) { + } catch (e: any) { const duration = Date.now() - start; const message = new TestMessage(e.message); message.location = new Location(item.uri!, item.range!); @@ -61,5 +69,5 @@ export class TestMethod implements ITestCase { return false; } - } + } } diff --git a/src/TestProvider/TestCases/index.ts b/src/TestProvider/TestCases/index.ts index e575e67..e3d9e2a 100644 --- a/src/TestProvider/TestCases/index.ts +++ b/src/TestProvider/TestCases/index.ts @@ -1,6 +1,6 @@ -export * from './ITestCase'; -export * from './TestMethod'; -export * from './TestClass'; -export * from './TestDirectory'; -export * from './TestCaseRepository'; -export * from './TestCaseNode'; +export * from "./ITestCase"; +export * from "./TestMethod"; +export * from "./TestClass"; +export * from "./TestDirectory"; +export * from "./TestCaseRepository"; +export * from "./TestCaseNode"; diff --git a/src/TestProvider/TestExplorerFeature.ts b/src/TestProvider/TestExplorerFeature.ts index 990964c..9a65c66 100644 --- a/src/TestProvider/TestExplorerFeature.ts +++ b/src/TestProvider/TestExplorerFeature.ts @@ -1,67 +1,97 @@ -import * as vscode from 'vscode'; -import { ITestCase, createOrUpdateFromPath, deleteFromUri, gatherTestItems, testData } from './TestCases'; -import path = require('path'); +import * as vscode from "vscode"; +import { + ITestCase, + createOrUpdateFromPath, + deleteFromUri, + gatherTestItems, + testData, +} from "./TestCases"; +import path = require("path"); let controller: vscode.TestController; export async function addTestExplorerFeature(context: vscode.ExtensionContext) { - const testExplorerEnabled = vscode.workspace.getConfiguration('phpunit').get('testExplorer.enabled', false); + const testExplorerEnabled = vscode.workspace + .getConfiguration("phpunit") + .get("testExplorer.enabled", false); if (!testExplorerEnabled) { return; } - const ctrl = vscode.tests.createTestController('phpunitTestController', 'Phpunit'); + const ctrl = vscode.tests.createTestController( + "phpunitTestController", + "Phpunit", + ); controller = ctrl; - context.subscriptions.push(ctrl); - - const fileChangedEmitter = new vscode.EventEmitter(); - const watchingTests = new Map(); - fileChangedEmitter.event(uri => { - if (watchingTests.has('ALL')) { - startTestRun(new vscode.TestRunRequest(undefined, undefined, watchingTests.get('ALL'), true)); - return; - } - - const include: vscode.TestItem[] = []; - let profile: vscode.TestRunProfile | undefined; - for (const [item, thisProfile] of watchingTests) { - const cast = item as vscode.TestItem; - if (cast.uri?.toString() == uri.toString()) { - include.push(cast); - profile = thisProfile; - } - } - - if (include.length) { - startTestRun(new vscode.TestRunRequest(include, undefined, profile, true)); - } - }); - - const runHandler = (request: vscode.TestRunRequest, cancellation: vscode.CancellationToken) => { - if (!request.continuous) { - return startTestRun(request); - } - - if (request.include === undefined) { - watchingTests.set('ALL', request.profile); - cancellation.onCancellationRequested(() => watchingTests.delete('ALL')); - } else { - request.include.forEach(item => watchingTests.set(item, request.profile)); - cancellation.onCancellationRequested(() => request.include!.forEach(item => watchingTests.delete(item))); - } - }; - - const startTestRun = (request: vscode.TestRunRequest) => { - const queue: { test: vscode.TestItem; data: ITestCase }[] = []; - const run = ctrl.createTestRun(request); - - const discoverTests = async (tests: Iterable) => { - for (const test of tests) { - if (request.exclude?.includes(test)) { - continue; - } - - const data = testData.get(test)!; + context.subscriptions.push(ctrl); + + const fileChangedEmitter = new vscode.EventEmitter(); + const watchingTests = new Map< + vscode.TestItem | "ALL", + vscode.TestRunProfile | undefined + >(); + fileChangedEmitter.event((uri) => { + if (watchingTests.has("ALL")) { + startTestRun( + new vscode.TestRunRequest( + undefined, + undefined, + watchingTests.get("ALL"), + true, + ), + ); + return; + } + + const include: vscode.TestItem[] = []; + let profile: vscode.TestRunProfile | undefined; + for (const [item, thisProfile] of watchingTests) { + const cast = item as vscode.TestItem; + if (cast.uri?.toString() == uri.toString()) { + include.push(cast); + profile = thisProfile; + } + } + + if (include.length) { + startTestRun( + new vscode.TestRunRequest(include, undefined, profile, true), + ); + } + }); + + const runHandler = ( + request: vscode.TestRunRequest, + cancellation: vscode.CancellationToken, + ) => { + if (!request.continuous) { + return startTestRun(request); + } + + if (request.include === undefined) { + watchingTests.set("ALL", request.profile); + cancellation.onCancellationRequested(() => watchingTests.delete("ALL")); + } else { + request.include.forEach((item) => + watchingTests.set(item, request.profile), + ); + cancellation.onCancellationRequested(() => + request.include!.forEach((item) => watchingTests.delete(item)), + ); + } + }; + + const startTestRun = (request: vscode.TestRunRequest) => { + const queue: { test: vscode.TestItem; data: ITestCase }[] = []; + const run = ctrl.createTestRun(request); + + const discoverTests = async (tests: Iterable) => { + for (const test of tests) { + if (request.exclude?.includes(test)) { + continue; + } + + const data = testData.get(test)!; // if (!data.isResolved) { // if (data instanceof TestDirectory) { // await findTestsInDirectory(ctrl, test.uri!, test); @@ -69,135 +99,177 @@ export async function addTestExplorerFeature(context: vscode.ExtensionContext) { // } run.enqueued(test); queue.push({ test, data }); - } - }; - - const runTestQueue = async () => { - for (const { test, data } of queue) { - run.appendOutput(`Running ${test.id}\r\n`); - if (run.token.isCancellationRequested) { - run.skipped(test); - } else { - run.started(test); - await data.run(test, run); - } - - run.appendOutput(`Completed ${test.id}\r\n`); - } - - run.end(); - }; - - discoverTests(request.include ?? gatherTestItems(ctrl.items)).then(runTestQueue); - }; - - ctrl.refreshHandler = async () => { - await Promise.all(getWorkspaceTestPatterns().map(({ pattern, exclude }) => findInitialTests(ctrl, pattern, exclude))); - }; - - ctrl.createRunProfile('Run Tests', vscode.TestRunProfileKind.Run, runHandler, true, undefined, true); - - ctrl.resolveHandler = async item => { - if (!item) { - context.subscriptions.push(...startWatchingWorkspace(ctrl, fileChangedEmitter)); - return; - } + } + }; + + const runTestQueue = async () => { + for (const { test, data } of queue) { + run.appendOutput(`Running ${test.id}\r\n`); + if (run.token.isCancellationRequested) { + run.skipped(test); + } else { + run.started(test); + await data.run(test, run); + } + + run.appendOutput(`Completed ${test.id}\r\n`); + } - // const data = testData.get(item)!; + run.end(); + }; + + discoverTests(request.include ?? gatherTestItems(ctrl.items)).then( + runTestQueue, + ); + }; + + ctrl.refreshHandler = async () => { + await Promise.all( + getWorkspaceTestPatterns().map(({ pattern, exclude }) => + findInitialTests(ctrl, pattern, exclude), + ), + ); + }; + + ctrl.createRunProfile( + "Run Tests", + vscode.TestRunProfileKind.Run, + runHandler, + true, + undefined, + true, + ); + + ctrl.resolveHandler = async (item) => { + if (!item) { + context.subscriptions.push( + ...startWatchingWorkspace(ctrl, fileChangedEmitter), + ); + return; + } + + // const data = testData.get(item)!; // if (item.canResolveChildren) { // await findTestsInDirectory(ctrl, item.uri!, item); // } // TODO: implement this // await data.updateFromDisk(ctrl, item); - }; + }; - for (const document of vscode.workspace.textDocuments) { - updateNodeForDocument(document); - } + for (const document of vscode.workspace.textDocuments) { + updateNodeForDocument(document); + } - context.subscriptions.push( - vscode.workspace.onDidOpenTextDocument(updateNodeForDocument), - vscode.workspace.onDidChangeTextDocument(async (e) => { + context.subscriptions.push( + vscode.workspace.onDidOpenTextDocument(updateNodeForDocument), + vscode.workspace.onDidChangeTextDocument(async (e) => { deleteFromUri(controller, controller.items, e.document.uri); await updateNodeForDocument(e.document); }), - ); + ); } function getWorkspaceTestPatterns() { - if (!vscode.workspace.workspaceFolders) { - return []; - } - - return vscode.workspace.workspaceFolders.map(workspaceFolder => ({ - workspaceFolder, - pattern: new vscode.RelativePattern(workspaceFolder, '**/tests/**/*Test.php'), - exclude: new vscode.RelativePattern(workspaceFolder, '**/{.git,node_modules,vendor}/**'), - })); + if (!vscode.workspace.workspaceFolders) { + return []; + } + + return vscode.workspace.workspaceFolders.map((workspaceFolder) => ({ + workspaceFolder, + pattern: new vscode.RelativePattern( + workspaceFolder, + "**/tests/**/*Test.php", + ), + exclude: new vscode.RelativePattern( + workspaceFolder, + "**/{.git,node_modules,vendor}/**", + ), + })); } async function updateNodeForDocument(e: vscode.TextDocument) { - if (e.uri.scheme !== 'file') { + if (e.uri.scheme !== "file") { return; } - if (!e.uri.path.endsWith('Test.php')) { + if (!e.uri.path.endsWith("Test.php")) { return; } - const wsPattern = getWorkspaceTestPatterns() - .find(({ workspaceFolder }) => e.uri.fsPath.startsWith(workspaceFolder.uri.fsPath)); + const wsPattern = getWorkspaceTestPatterns().find(({ workspaceFolder }) => + e.uri.fsPath.startsWith(workspaceFolder.uri.fsPath), + ); if (!wsPattern) { return; } - const { commonDirectory } = await getFilesAndCommonDirectory(wsPattern.pattern, wsPattern.exclude); + const { commonDirectory } = await getFilesAndCommonDirectory( + wsPattern.pattern, + wsPattern.exclude, + ); await createOrUpdateFromPath(controller, e.uri.fsPath, commonDirectory); } -async function findInitialTests(controller: vscode.TestController, pattern: vscode.GlobPattern, exclude: vscode.GlobPattern) { - const { files, commonDirectory } = await getFilesAndCommonDirectory(pattern, exclude); +async function findInitialTests( + controller: vscode.TestController, + pattern: vscode.GlobPattern, + exclude: vscode.GlobPattern, +) { + const { files, commonDirectory } = await getFilesAndCommonDirectory( + pattern, + exclude, + ); for (const file of files) { await createOrUpdateFromPath(controller, file.fsPath, commonDirectory); } } -async function getFilesAndCommonDirectory(pattern: vscode.GlobPattern, exclude: vscode.GlobPattern) { +async function getFilesAndCommonDirectory( + pattern: vscode.GlobPattern, + exclude: vscode.GlobPattern, +) { const files = await vscode.workspace.findFiles(pattern, exclude); - const directories = files.map(file => path.dirname(file.fsPath)); + const directories = files.map((file) => path.dirname(file.fsPath)); const commonDirectory = directories.reduce((common, dir) => { - let i = 0; - while (i < common.length && common[i] === dir[i]) { - i++; - } - return common.substring(0, i); + let i = 0; + while (i < common.length && common[i] === dir[i]) { + i++; + } + return common.substring(0, i); }, directories[0]); return { files, commonDirectory }; } -function startWatchingWorkspace(controller: vscode.TestController, fileChangedEmitter: vscode.EventEmitter) { - return getWorkspaceTestPatterns().map(({ workspaceFolder, pattern, exclude }) => { - const watcher = vscode.workspace.createFileSystemWatcher(pattern); - - watcher.onDidCreate(async uri => { - const document = await vscode.workspace.openTextDocument(uri); - updateNodeForDocument(document); - fileChangedEmitter.fire(uri); - }); - watcher.onDidChange(async uri => { - deleteFromUri(controller, controller.items, uri); - - const document = await vscode.workspace.openTextDocument(uri); - await updateNodeForDocument(document); - - fileChangedEmitter.fire(uri); - }); - watcher.onDidDelete(uri => deleteFromUri(controller, controller.items, uri)); - - findInitialTests(controller, pattern, exclude); - - return watcher; - }); +function startWatchingWorkspace( + controller: vscode.TestController, + fileChangedEmitter: vscode.EventEmitter, +) { + return getWorkspaceTestPatterns().map( + ({ workspaceFolder, pattern, exclude }) => { + const watcher = vscode.workspace.createFileSystemWatcher(pattern); + + watcher.onDidCreate(async (uri) => { + const document = await vscode.workspace.openTextDocument(uri); + updateNodeForDocument(document); + fileChangedEmitter.fire(uri); + }); + watcher.onDidChange(async (uri) => { + deleteFromUri(controller, controller.items, uri); + + const document = await vscode.workspace.openTextDocument(uri); + await updateNodeForDocument(document); + + fileChangedEmitter.fire(uri); + }); + watcher.onDidDelete((uri) => + deleteFromUri(controller, controller.items, uri), + ); + + findInitialTests(controller, pattern, exclude); + + return watcher; + }, + ); } diff --git a/src/TestProvider/TestFileParser.ts b/src/TestProvider/TestFileParser.ts index 59ab762..620f3b7 100644 --- a/src/TestProvider/TestFileParser.ts +++ b/src/TestProvider/TestFileParser.ts @@ -1,10 +1,17 @@ import { Range, Uri } from "vscode"; -import { Class, CommentBlock, Engine, Identifier, Method, Namespace } from 'php-parser'; +import { + Class, + CommentBlock, + Engine, + Identifier, + Method, + Namespace, +} from "php-parser"; import { ITestCase, TestCaseNode, TestClass, TestMethod } from "./TestCases"; const engine = new Engine({ ast: { - withPositions: true + withPositions: true, }, parser: { debug: false, @@ -23,66 +30,88 @@ const engine = new Engine({ export class TestFileParser { public parse = (text: string, uri: Uri): Array => { const ast = engine.parseCode(text, uri.fsPath); - + const testCaseNodes = new Array(); for (const node of ast.children) { - if (node.kind === 'class') { + if (node.kind === "class") { testCaseNodes.push(this.parseClass(node as Class, uri)); - } else if (node.kind === 'namespace') { + } else if (node.kind === "namespace") { testCaseNodes.push(this.parseNamespace(node as Namespace, uri)); } } - + return testCaseNodes; }; - + private parseNamespace(node: Namespace, uri: Uri): TestCaseNode { - const testCaseNode = new TestCaseNode('namespace', node.name, new Range(node.loc!.start.line - 1, 0, node.loc!.end.line - 1, 0)); - + const testCaseNode = new TestCaseNode( + "namespace", + node.name, + new Range(node.loc!.start.line - 1, 0, node.loc!.end.line - 1, 0), + ); + for (const child of node.children) { - if (child.kind === 'class') { + if (child.kind === "class") { const testCaseClassNode = this.parseClass(child as Class, uri); testCaseClassNode.parent = testCaseNode; testCaseNode.children.push(testCaseClassNode); } } - + return testCaseNode; } - + private parseClass(node: Class, uri: Uri): TestCaseNode { - const className = typeof node.name === 'string' ? node.name : (node.name as Identifier).name; - const testCaseNode = new TestCaseNode('class', className, new Range(node.loc!.start.line - 1, 0, node.loc!.end.line - 1, 0)); - + const className = + typeof node.name === "string" + ? node.name + : (node.name as Identifier).name; + const testCaseNode = new TestCaseNode( + "class", + className, + new Range(node.loc!.start.line - 1, 0, node.loc!.end.line - 1, 0), + ); + for (const child of node.body) { - if (child.kind !== 'method') { - continue; - } - - const testCaseMethodNode = this.parseMethod(child as Method, uri); - if (testCaseMethodNode) { - testCaseMethodNode.parent = testCaseNode; - testCaseNode.children.push(testCaseMethodNode); - } + if (child.kind !== "method") { + continue; + } + + const testCaseMethodNode = this.parseMethod(child as Method, uri); + if (testCaseMethodNode) { + testCaseMethodNode.parent = testCaseNode; + testCaseNode.children.push(testCaseMethodNode); + } } - + return testCaseNode; } - + private parseMethod(node: Method, uri: Uri): TestCaseNode | null { const leadingComments = node.leadingComments || []; const hasTestAnnotation = leadingComments.find((comment: CommentBlock) => { - return comment.kind === 'commentblock' && comment.value.indexOf('* @test') != -1; + return ( + comment.kind === "commentblock" && + comment.value.indexOf("* @test") != -1 + ); }); - - const methodName = typeof node.name === 'string' ? node.name : (node.name as Identifier).name; - - if (!methodName.startsWith('test') && !hasTestAnnotation) { - return null; + + const methodName = + typeof node.name === "string" + ? node.name + : (node.name as Identifier).name; + + if (!methodName.startsWith("test") && !hasTestAnnotation) { + return null; } - - const range = new Range(node.loc!.start.line - 1, 0, node.loc!.end.line - 1, 0); - - return new TestCaseNode('method', methodName, range); + + const range = new Range( + node.loc!.start.line - 1, + 0, + node.loc!.end.line - 1, + 0, + ); + + return new TestCaseNode("method", methodName, range); } } diff --git a/src/Utils/escape-string-regexp.ts b/src/Utils/escape-string-regexp.ts index bbce50d..87cd3e7 100644 --- a/src/Utils/escape-string-regexp.ts +++ b/src/Utils/escape-string-regexp.ts @@ -1,11 +1,9 @@ export default function escapeStringRegexp(string: string) { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); - } + if (typeof string !== "string") { + throw new TypeError("Expected a string"); + } - // Escape characters with special meaning either inside or outside character sets. - // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. - return string - .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - .replace(/-/g, '\\x2d'); + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); } diff --git a/src/extension.ts b/src/extension.ts index 1982f1e..6445580 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -11,9 +11,12 @@ import { addTestExplorerFeature } from "./TestProvider/TestExplorerFeature"; export let PHPUnitTestRunner: TestRunner; export function activate(context: vscode.ExtensionContext): IMyExtensionApi { - const testOutputFile = path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'test-output.txt'); + const testOutputFile = path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "test-output.txt", + ); const myExtensionApi = { - testRedirectedOutputFile: testOutputFile + testRedirectedOutputFile: testOutputFile, }; let taskCommand: string; @@ -21,67 +24,69 @@ export function activate(context: vscode.ExtensionContext): IMyExtensionApi { const outputChannel = vscode.window.createOutputChannel("phpunit"); PHPUnitTestRunner = new TestRunner(outputChannel, { setTaskCommand: (command: string, matcher?: string) => { - if (process.env.VSCODE_PHPUNIT_TEST === 'true') { - taskCommand = command + ' > ' + testOutputFile; - } - else { + if (process.env.VSCODE_PHPUNIT_TEST === "true") { + taskCommand = command + " > " + testOutputFile; + } else { taskCommand = command; } problemMatcher = matcher; - } + }, }); context.subscriptions.push( - vscode.commands.registerCommand("phpunit.Test", async (argBuilder: PhpunitArgBuilder) => { - if (argBuilder) { - return await PHPUnitTestRunner.runArgs(argBuilder); - } else { - return await PHPUnitTestRunner.run("test"); - } - }) + vscode.commands.registerCommand( + "phpunit.Test", + async (argBuilder: PhpunitArgBuilder) => { + if (argBuilder) { + return await PHPUnitTestRunner.runArgs(argBuilder); + } else { + return await PHPUnitTestRunner.run("test"); + } + }, + ), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.TestNearest", async () => { return PHPUnitTestRunner.run("nearest-test"); - }) + }), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.TestSuite", async () => { return PHPUnitTestRunner.run("suite"); - }) + }), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.TestDirectory", async () => { return PHPUnitTestRunner.run("directory"); - }) + }), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.TestDirectory2", async () => { return PHPUnitTestRunner.run("directory2"); - }) + }), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.TestDirectory3", async () => { return PHPUnitTestRunner.run("directory3"); - }) + }), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.RerunLastTest", async () => { return PHPUnitTestRunner.run("rerun-last-test"); - }) + }), ); context.subscriptions.push( vscode.commands.registerCommand("phpunit.TestingStop", async () => { return PHPUnitTestRunner.stop(); - }) + }), ); context.subscriptions.push( @@ -93,21 +98,18 @@ export function activate(context: vscode.ExtensionContext): IMyExtensionApi { vscode.TaskScope.Workspace, "run", "phpunit", - new vscode.ShellExecution( - taskCommand, - { - env: vscode.workspace.getConfiguration('phpunit').envVars - }, - ), - problemMatcher || "$phpunit" - ) + new vscode.ShellExecution(taskCommand, { + env: vscode.workspace.getConfiguration("phpunit").envVars, + }), + problemMatcher || "$phpunit", + ), ]; }, // Hack around typescript compiler resolveTask: (task: vscode.Task, token: vscode.CancellationToken) => { return null as any as vscode.ProviderResult; - } - }) + }, + }), ); addCodeLensFeature(context); diff --git a/src/phpunittest.ts b/src/phpunittest.ts index 7e25826..9527da2 100644 --- a/src/phpunittest.ts +++ b/src/phpunittest.ts @@ -28,33 +28,29 @@ export class TestRunner { public readonly regex = { class: /class\s+(\w*)\s*\{?/gi, - method: /\s*public*\s+function\s+(\w*)\s*\(/gi + method: /\s*public*\s+function\s+(\w*)\s*\(/gi, }; constructor( channel: vscode.OutputChannel, - bootstrapBridge: IExtensionBootstrapBridge + bootstrapBridge: IExtensionBootstrapBridge, ) { this.channel = channel; this.bootstrapBridge = bootstrapBridge; } public getClosestMethodAboveActiveLine( - editor: vscode.TextEditor + editor: vscode.TextEditor, ): string | null { for (let i = editor.selection.active.line; i > 0; --i) { const line = editor.document.lineAt(i); - let regexResult = this.regex.method.exec( - line.text - ); + let regexResult = this.regex.method.exec(line.text); if (regexResult) { return regexResult[1].toString().trim(); } - regexResult = this.regex.class.exec( - line.text - ); + regexResult = this.regex.class.exec(line.text); if (regexResult) { return regexResult[1].toString().trim(); @@ -69,7 +65,6 @@ export class TestRunner { argBuilder: PhpunitArgBuilder, config: any, ): Promise { - const editor = vscode.window.activeTextEditor; if (type === "test" && editor) { if ( @@ -78,11 +73,14 @@ export class TestRunner { ) { argBuilder.withConfig(editor.document.uri.fsPath); - return await this.resolveSuiteArgsAsync(argBuilder, editor.document.getText()); + return await this.resolveSuiteArgsAsync( + argBuilder, + editor.document.getText(), + ); } const range = editor.document.getWordRangeAtPosition( - editor.selection.active + editor.selection.active, ); if (range) { const line = editor.document.lineAt(range.start.line); @@ -105,25 +103,21 @@ export class TestRunner { let testableList = []; // Gather the class and functions to show in the quick pick window. { - const closestMethod = this.getClosestMethodAboveActiveLine( - editor - ); + const closestMethod = this.getClosestMethodAboveActiveLine(editor); if (closestMethod) { testableList.push("function - " + closestMethod); } const parsedPhpClass = await parsePhpToObject( - editor.document.fileName + editor.document.fileName, ); testableList.push("class - " + parsedPhpClass.name); testableList = testableList.concat( - parsedPhpClass.methods.public.map(m => "function - " + m) + parsedPhpClass.methods.public.map((m) => "function - " + m), ); } - const selectedTest = await vscode.window.showQuickPick( - testableList - ); + const selectedTest = await vscode.window.showQuickPick(testableList); if (!selectedTest) { return false; } @@ -142,7 +136,9 @@ export class TestRunner { } else if (type === "nearest-test" && editor) { const closestMethod = this.getClosestMethodAboveActiveLine(editor); if (!closestMethod) { - console.error("No method found above the cursor. Make sure the cursor is close to a method."); + console.error( + "No method found above the cursor. Make sure the cursor is close to a method.", + ); return false; } @@ -154,13 +150,14 @@ export class TestRunner { } else if (type === "suite") { const files = await vscode.workspace.findFiles( "**/phpunit.xml**", - "**/vendor/**" + "**/vendor/**", ); - let selectedSuiteFile = files && files.length === 1 ? files[0].fsPath : undefined; + let selectedSuiteFile = + files && files.length === 1 ? files[0].fsPath : undefined; if (files && files.length > 1) { selectedSuiteFile = await vscode.window.showQuickPick( - files.map(f => f.fsPath), - { placeHolder: "Choose test suite file..." } + files.map((f) => f.fsPath), + { placeHolder: "Choose test suite file..." }, ); } @@ -177,12 +174,15 @@ export class TestRunner { resolve(data); } }); - } + }, ); argBuilder.withConfig(selectedSuiteFile); - return await this.resolveSuiteArgsAsync(argBuilder, selectedSuiteFileContent); + return await this.resolveSuiteArgsAsync( + argBuilder, + selectedSuiteFileContent, + ); } else if (type === "directory") { if (!editor) { console.error("Please open a file in the directory you want to test."); @@ -190,7 +190,10 @@ export class TestRunner { return false; } - const currentDir = editor.document.uri.fsPath.replace(/(\/|\\)\w*\.php$/i, ""); + const currentDir = editor.document.uri.fsPath.replace( + /(\/|\\)\w*\.php$/i, + "", + ); argBuilder.addDirectoryOrFile(currentDir); return true; @@ -203,7 +206,7 @@ export class TestRunner { const currentDir = editor.document.uri.fsPath.replace( /(\/|\\)[^/\\]+(\/|\\)\w*\.php$/i, - "" + "", ); argBuilder.addDirectoryOrFile(currentDir); @@ -217,7 +220,7 @@ export class TestRunner { const currentDir = editor.document.uri.fsPath.replace( /(\/|\\)[^/\\]+(\/|\\)[^/\\]+(\/|\\)\w*\.php$/i, - "" + "", ); argBuilder.addDirectoryOrFile(currentDir); @@ -227,7 +230,9 @@ export class TestRunner { return false; } - public async getDriver(order?: string[]): Promise { + public async getDriver( + order?: string[], + ): Promise { const drivers: IPhpUnitDriver[] = [ new PhpUnitDrivers.Path(), new PhpUnitDrivers.Composer(), @@ -237,7 +242,7 @@ export class TestRunner { new PhpUnitDrivers.DockerContainer(), new PhpUnitDrivers.Docker(), new PhpUnitDrivers.Ssh(), - new PhpUnitDrivers.Legacy() + new PhpUnitDrivers.Legacy(), ]; function arrayUnique(array: any[]) { @@ -252,7 +257,7 @@ export class TestRunner { return a; } - order = arrayUnique((order || []).concat(drivers.map(d => d.name))); + order = arrayUnique((order || []).concat(drivers.map((d) => d.name))); const sortedDrivers = drivers.sort((a, b) => { return order!.indexOf(a.name) - order!.indexOf(b.name); @@ -281,15 +286,20 @@ export class TestRunner { argBuilder.addArgs(configArgs); const colors = config.get("colors"); - if (colors && (configArgs.indexOf(colors) === -1)) { - argBuilder.withColors(colors.replace(/--colors=?/i, '') as 'never' | 'auto' | 'always'); + if (colors && configArgs.indexOf(colors) === -1) { + argBuilder.withColors( + colors.replace(/--colors=?/i, "") as "never" | "auto" | "always", + ); } const pathMappings = config.get<{ [key: string]: string }>("paths"); if (pathMappings) { - argBuilder.withPathMappings(pathMappings, vscode.workspace.workspaceFolders![0].uri.fsPath); + argBuilder.withPathMappings( + pathMappings, + vscode.workspace.workspaceFolders![0].uri.fsPath, + ); } - + this.lastArgBuilder = argBuilder; const runConfig = await driver.run(argBuilder.buildArgs()); @@ -298,25 +308,33 @@ export class TestRunner { this.bootstrapBridge.setTaskCommand( runConfig.command, - runConfig.problemMatcher + runConfig.problemMatcher, ); - if (process.env.VSCODE_PHPUNIT_TEST === 'true') { + if (process.env.VSCODE_PHPUNIT_TEST === "true") { console.debug(runConfig.command); } if (childProcess) { if (runConfig.args.length > 0) { if (runConfig.args[0].startsWith("'")) { - runConfig.args[0] = runConfig.args[0].replace(/^'/g, '').replace(/'$/g, ''); + runConfig.args[0] = runConfig.args[0] + .replace(/^'/g, "") + .replace(/'$/g, ""); } } - return await new Promise(r => r(spawnSync(runConfig.exec, runConfig.args, { encoding: "utf8" }))); + return await new Promise((r) => + r( + spawnSync(runConfig.exec, runConfig.args, { + encoding: "utf8", + }), + ), + ); } else { await vscode.commands.executeCommand("workbench.action.terminal.clear"); await vscode.commands.executeCommand( "workbench.action.tasks.runTask", - "phpunit: run" + "phpunit: run", ); } } @@ -338,23 +356,28 @@ export class TestRunner { } else { const configArgs = config.get("args", []); argBuilder.addArgs(configArgs); - + const colors = config.get("colors"); - if (colors && (configArgs.indexOf(colors) === -1)) { - argBuilder.withColors(colors.replace(/--colors=?/i, '') as 'never' | 'auto' | 'always'); + if (colors && configArgs.indexOf(colors) === -1) { + argBuilder.withColors( + colors.replace(/--colors=?/i, "") as "never" | "auto" | "always", + ); } - + const pathMappings = config.get<{ [key: string]: string }>("paths"); if (pathMappings) { - argBuilder.withPathMappings(pathMappings, vscode.workspace.workspaceFolders![0].uri.fsPath); + argBuilder.withPathMappings( + pathMappings, + vscode.workspace.workspaceFolders![0].uri.fsPath, + ); } - + const preferRunClassTestOverQuickPickWindow = config.get( "preferRunClassTestOverQuickPickWindow", - false + false, ); const shouldRun = await this.resolveContextArgs(type, argBuilder, { - preferRunClassTestOverQuickPickWindow + preferRunClassTestOverQuickPickWindow, }); if (!shouldRun) { @@ -370,33 +393,35 @@ export class TestRunner { this.bootstrapBridge.setTaskCommand( runConfig.command, - runConfig.problemMatcher + runConfig.problemMatcher, ); - if (process.env.VSCODE_PHPUNIT_TEST === 'true') { + if (process.env.VSCODE_PHPUNIT_TEST === "true") { console.debug(runConfig.command); } await vscode.commands.executeCommand("workbench.action.terminal.clear"); await vscode.commands.executeCommand( "workbench.action.tasks.runTask", - "phpunit: run" + "phpunit: run", ); } public async stop() { await vscode.commands.executeCommand( "workbench.action.tasks.terminate", - "phpunit: run" + "phpunit: run", ); } private async resolveSuiteArgsAsync( argBuilder: PhpunitArgBuilder, - fileContent: string + fileContent: string, ): Promise { const testSuitesMatch = fileContent.match(/]+name="[^"]+">/g); - const testSuites = testSuitesMatch ? testSuitesMatch.map(v => v.match(/name="([^"]+)"/)![1]) : null; + const testSuites = testSuitesMatch + ? testSuitesMatch.map((v) => v.match(/name="([^"]+)"/)![1]) + : null; if (!testSuites || testSuites.length === 0) { return false; @@ -406,11 +431,11 @@ export class TestRunner { argBuilder.addSuite(testSuites[0]); return true; - } + } const selectedSuite = await vscode.window.showQuickPick( ["Run All Test Suites...", ...testSuites], - { placeHolder: "Choose test suite..." } + { placeHolder: "Choose test suite..." }, ); if (!selectedSuite) { diff --git a/src/test/php-project/composer.json b/src/test/php-project/composer.json index eef60f4..e365b2d 100644 --- a/src/test/php-project/composer.json +++ b/src/test/php-project/composer.json @@ -1,18 +1,17 @@ { - "name": "vscode-phpunit/php-project", - "description": "Tests will run against this project", - "type": "project", - "require": { - }, - "require-dev": { - "phpunit/phpunit": "^10.4" - }, - "license": "MIT", - "autoload": { - "psr-4": { - "Math\\": "src/Math", - "Science\\": "src/Science", - "Colors\\": "src/Colors" - } + "name": "vscode-phpunit/php-project", + "description": "Tests will run against this project", + "type": "project", + "require": {}, + "require-dev": { + "phpunit/phpunit": "^10.4" + }, + "license": "MIT", + "autoload": { + "psr-4": { + "Math\\": "src/Math", + "Science\\": "src/Science", + "Colors\\": "src/Colors" } + } } diff --git a/src/test/php-project/composer.lock b/src/test/php-project/composer.lock index fb397bb..169d13f 100644 --- a/src/test/php-project/composer.lock +++ b/src/test/php-project/composer.lock @@ -1,1632 +1,1480 @@ { - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "d9753063d0baac3c1808b0307fd82642", - "packages": [], - "packages-dev": [ - { - "name": "myclabs/deep-copy", - "version": "1.11.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2023-03-08T13:26:56+00:00" - }, + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "d9753063d0baac3c1808b0307fd82642", + "packages": [], + "packages-dev": [ + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": ["src/DeepCopy/deep_copy.php"], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["MIT"], + "description": "Create deep copies (clones) of your objects", + "keywords": ["clone", "copy", "duplicate", "object", "object graph"], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ { - "name": "nikic/php-parser", - "version": "v4.17.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" - }, - "time": "2023-08-13T19:53:39+00:00" - }, + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.17.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": ["bin/php-parse"], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": ["parser", "php"], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + }, + "time": "2023-08-13T19:53:39+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" }, { - "name": "phpunit/php-code-coverage", - "version": "10.1.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "355324ca4980b8916c18b9db29f3ef484078f26e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e", - "reference": "355324ca4980b8916c18b9db29f3ef484078f26e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.1" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.7" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-10-04T15:34:17+00:00" + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "phpunit/php-file-iterator", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T06:24:48+00:00" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ { - "name": "phpunit/php-invoker", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:56:09+00:00" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" }, { - "name": "phpunit/php-text-template", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T14:07:24+00:00" + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "phpunit/php-timer", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:57:52+00:00" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "355324ca4980b8916c18b9db29f3ef484078f26e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e", + "reference": "355324ca4980b8916c18b9db29f3ef484078f26e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ { - "name": "phpunit/phpunit", - "version": "10.4.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", - "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.5", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-invoker": "^4.0", - "phpunit/php-text-template": "^3.0", - "phpunit/php-timer": "^6.0", - "sebastian/cli-parser": "^2.0", - "sebastian/code-unit": "^2.0", - "sebastian/comparator": "^5.0", - "sebastian/diff": "^5.0", - "sebastian/environment": "^6.0", - "sebastian/exporter": "^5.1", - "sebastian/global-state": "^6.0.1", - "sebastian/object-enumerator": "^5.0", - "sebastian/recursion-context": "^5.0", - "sebastian/type": "^4.0", - "sebastian/version": "^4.0" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.4-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.2" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2023-10-26T07:21:45+00:00" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": ["coverage", "testing", "xunit"], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.7" + }, + "funding": [ { - "name": "sebastian/cli-parser", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:15+00:00" - }, + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-10-04T15:34:17+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": ["filesystem", "iterator"], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:59:15+00:00" - }, + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": ["process"], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": ["template"], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ { - "name": "sebastian/comparator", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-14T13:18:12+00:00" + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": ["timer"], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", + "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": ["phpunit"], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.4-dev" + } + }, + "autoload": { + "files": ["src/Framework/Assert/Functions.php"], + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": ["phpunit", "testing", "xunit"], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.2" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" }, { - "name": "sebastian/complexity", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.10", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-09-28T11:50:59+00:00" + "url": "https://github.com/sebastianbergmann", + "type": "github" }, { - "name": "sebastian/diff", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-05-01T07:48:21+00:00" + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-10-26T07:21:45+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "name": "sebastian/environment", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-04-11T05:39:26+00:00" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "name": "sebastian/exporter", - "version": "5.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-09-24T13:22:09+00:00" + "name": "Volker Dusch", + "email": "github@wallbash.com" }, { - "name": "sebastian/global-state", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-07-19T07:19:23+00:00" + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": ["comparator", "compare", "equality"], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-14T13:18:12+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-28T11:50:59+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "name": "sebastian/lines-of-code", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.10", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T09:25:50+00:00" + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": ["diff", "udiff", "unidiff", "unified diff"], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-01T07:48:21+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": ["Xdebug", "environment", "hhvm"], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-11T05:39:26+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "name": "sebastian/object-enumerator", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:08:32+00:00" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "name": "sebastian/object-reflector", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:06:18+00:00" + "name": "Volker Dusch", + "email": "github@wallbash.com" }, { - "name": "sebastian/recursion-context", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:05:40+00:00" + "name": "Adam Harvey", + "email": "aharvey@php.net" }, { - "name": "sebastian/type", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:10:45+00:00" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": ["export", "exporter"], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-24T13:22:09+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": ["global state"], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-19T07:19:23+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T09:25:50+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "name": "sebastian/version", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-07T11:34:05+00:00" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.6.0" + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": ["src/"] + }, + "notification-url": "https://packagist.org/downloads/", + "license": ["BSD-3-Clause"], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" } diff --git a/src/test/runTest.ts b/src/test/runTest.ts index e0ad770..1712c89 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -1,28 +1,31 @@ -import * as path from 'path'; +import * as path from "path"; -import { runTests } from '@vscode/test-electron'; +import { runTests } from "@vscode/test-electron"; async function main() { - try { - // The folder containing the Extension Manifest package.json - // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + try { + // The folder containing the Extension Manifest package.json + // Passed to `--extensionDevelopmentPath` + const extensionDevelopmentPath = path.resolve(__dirname, "../../"); - // The path to the extension test script - // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './suite/index'); - const workdir = path.resolve(extensionDevelopmentPath, 'src/test/php-project'); + // The path to the extension test script + // Passed to --extensionTestsPath + const extensionTestsPath = path.resolve(__dirname, "./suite/index"); + const workdir = path.resolve( + extensionDevelopmentPath, + "src/test/php-project", + ); - // Download VS Code, unzip it and run the integration test - await runTests({ + // Download VS Code, unzip it and run the integration test + await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: [workdir], }); - } catch (err) { - console.error('Failed to run tests'); - process.exit(1); - } + } catch (err) { + console.error("Failed to run tests"); + process.exit(1); + } } main(); diff --git a/src/test/suite/codelens.test.ts b/src/test/suite/codelens.test.ts index b5ce3a6..c181570 100644 --- a/src/test/suite/codelens.test.ts +++ b/src/test/suite/codelens.test.ts @@ -1,51 +1,81 @@ -import * as assert from 'assert'; +import * as assert from "assert"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import * as vscode from 'vscode'; +import * as vscode from "vscode"; // import * as myExtension from '../../extension'; -import path = require('path'); -import { PhpCodeLensProvider } from '../../CodeLens/PhpCodeLensProvider'; -import { PhpunitXmlCodeLensProvider } from '../../CodeLens/PhpunitXmlCodeLensProvider'; -import { PhpunitArgBuilder } from '../../PhpunitCommand/PhpunitArgBuilder'; +import path = require("path"); +import { PhpCodeLensProvider } from "../../CodeLens/PhpCodeLensProvider"; +import { PhpunitXmlCodeLensProvider } from "../../CodeLens/PhpunitXmlCodeLensProvider"; +import { PhpunitArgBuilder } from "../../PhpunitCommand/PhpunitArgBuilder"; -suite('CodeLens Test Suite', () => { - - test('Test AdditionTest.php', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Math/AdditionTest.php')); +suite("CodeLens Test Suite", () => { + test("Test AdditionTest.php", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Math/AdditionTest.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); const codeLensProvider = new PhpCodeLensProvider(); - const codeLenses = await codeLensProvider.provideCodeLenses(document, new vscode.CancellationTokenSource().token); + const codeLenses = await codeLensProvider.provideCodeLenses( + document, + new vscode.CancellationTokenSource().token, + ); assert.equal(codeLenses.length, 2); - assert.equal(codeLenses[0].command?.command, 'phpunit.Test'); - assert.equal(codeLenses[0].command?.title, 'Run test'); - assert.match((codeLenses[0].command?.arguments?.[0] as PhpunitArgBuilder).build(), /--filter .?testAdd.?/i); + assert.equal(codeLenses[0].command?.command, "phpunit.Test"); + assert.equal(codeLenses[0].command?.title, "Run test"); + assert.match( + (codeLenses[0].command?.arguments?.[0] as PhpunitArgBuilder).build(), + /--filter .?testAdd.?/i, + ); - assert.equal(codeLenses[1].command?.command, 'phpunit.Test'); - assert.equal(codeLenses[1].command?.title, 'Run tests'); - assert.match((codeLenses[1].command?.arguments?.[0] as PhpunitArgBuilder).build(), /--filter .?AdditionTest.?/i); - }); + assert.equal(codeLenses[1].command?.command, "phpunit.Test"); + assert.equal(codeLenses[1].command?.title, "Run tests"); + assert.match( + (codeLenses[1].command?.arguments?.[0] as PhpunitArgBuilder).build(), + /--filter .?AdditionTest.?/i, + ); + }); - test('Test phpunit.xml', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'phpunit.xml')); + test("Test phpunit.xml", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "phpunit.xml", + ), + ); const document = await vscode.workspace.openTextDocument(uri); const codeLensProvider = new PhpunitXmlCodeLensProvider(); - const codeLenses = await codeLensProvider.provideCodeLenses(document, new vscode.CancellationTokenSource().token); + const codeLenses = await codeLensProvider.provideCodeLenses( + document, + new vscode.CancellationTokenSource().token, + ); assert.equal(codeLenses.length, 3); - assert.equal(codeLenses[0].command?.command, 'phpunit.Test'); - assert.equal(codeLenses[0].command?.title, 'Run test'); - assert.match((codeLenses[0].command?.arguments?.[0] as PhpunitArgBuilder).build(), /--testsuite Math/i); + assert.equal(codeLenses[0].command?.command, "phpunit.Test"); + assert.equal(codeLenses[0].command?.title, "Run test"); + assert.match( + (codeLenses[0].command?.arguments?.[0] as PhpunitArgBuilder).build(), + /--testsuite Math/i, + ); - assert.equal(codeLenses[1].command?.command, 'phpunit.Test'); - assert.equal(codeLenses[1].command?.title, 'Run test'); - assert.match((codeLenses[1].command?.arguments?.[0] as PhpunitArgBuilder).build(), /--testsuite Science/i); + assert.equal(codeLenses[1].command?.command, "phpunit.Test"); + assert.equal(codeLenses[1].command?.title, "Run test"); + assert.match( + (codeLenses[1].command?.arguments?.[0] as PhpunitArgBuilder).build(), + /--testsuite Science/i, + ); - assert.equal(codeLenses[2].command?.command, 'phpunit.Test'); - assert.equal(codeLenses[2].command?.title, 'Run tests'); - assert.match((codeLenses[2].command?.arguments?.[0] as PhpunitArgBuilder).build(), /--configuration .*phpunit.xml/i); - }); + assert.equal(codeLenses[2].command?.command, "phpunit.Test"); + assert.equal(codeLenses[2].command?.title, "Run tests"); + assert.match( + (codeLenses[2].command?.arguments?.[0] as PhpunitArgBuilder).build(), + /--configuration .*phpunit.xml/i, + ); + }); }); diff --git a/src/test/suite/e2e.test.ts b/src/test/suite/e2e.test.ts index b12bef4..ea23d31 100644 --- a/src/test/suite/e2e.test.ts +++ b/src/test/suite/e2e.test.ts @@ -1,163 +1,254 @@ -import * as assert from 'assert'; +import * as assert from "assert"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import * as vscode from 'vscode'; +import * as vscode from "vscode"; // import * as myExtension from '../../extension'; -import path = require('path'); -import { before, beforeEach } from 'mocha'; -import * as fs from 'fs'; -import { IMyExtensionApi } from '../../MyExtensionApi'; -import * as sinon from 'sinon'; - -const getOnDidEndTaskProcessPromise = (outputFile: string): Promise<{ output: string, exitCode: number }> => { - return new Promise<{ output: string, exitCode: number }>((resolve, reject) => { - const disposable = vscode.tasks.onDidEndTaskProcess(async (e) => { - if (e.execution.task.source === 'phpunit' && e.execution.task.name === 'run') { - const output = await fs.promises.readFile(outputFile, 'utf-8'); +import path = require("path"); +import { before, beforeEach } from "mocha"; +import * as fs from "fs"; +import { IMyExtensionApi } from "../../MyExtensionApi"; +import * as sinon from "sinon"; + +const getOnDidEndTaskProcessPromise = ( + outputFile: string, +): Promise<{ output: string; exitCode: number }> => { + return new Promise<{ output: string; exitCode: number }>( + (resolve, reject) => { + const disposable = vscode.tasks.onDidEndTaskProcess(async (e) => { + if ( + e.execution.task.source === "phpunit" && + e.execution.task.name === "run" + ) { + const output = await fs.promises.readFile(outputFile, "utf-8"); disposable.dispose(); - resolve({ output, exitCode: e.exitCode === undefined ? 1 : e.exitCode }); - } - }); - }); + resolve({ + output, + exitCode: e.exitCode === undefined ? 1 : e.exitCode, + }); + } + }); + }, + ); }; let myExtensionApi: IMyExtensionApi; -suite('php-project e2e', () => { - +suite("php-project e2e", () => { before(async () => { - const ext = vscode.extensions.getExtension('emallin.phpunit'); - myExtensionApi = await ext?.activate() as IMyExtensionApi; + const ext = vscode.extensions.getExtension("emallin.phpunit"); + myExtensionApi = (await ext?.activate()) as IMyExtensionApi; }); beforeEach(async () => { sinon.restore(); }); - - test('phpunit.Test Class', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Math/AdditionTest.php')); + + test("phpunit.Test Class", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Math/AdditionTest.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document, { - selection: new vscode.Range(5, 0, 5, 0) // Set the cursor on the class line in the AdditionTest class + selection: new vscode.Range(5, 0, 5, 0), // Set the cursor on the class line in the AdditionTest class }); - await vscode.workspace.getConfiguration('phpunit').update('preferRunClassTestOverQuickPickWindow', true); + await vscode.workspace + .getConfiguration("phpunit") + .update("preferRunClassTestOverQuickPickWindow", true); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.Test'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.Test"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - }); + }); - test('phpunit.Test Function', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Math/AdditionTest.php')); + test("phpunit.Test Function", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Math/AdditionTest.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document, { - selection: new vscode.Range(6, 20, 6, 27) // Select the first function name in AdditionTest + selection: new vscode.Range(6, 20, 6, 27), // Select the first function name in AdditionTest }); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.Test'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.Test"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - }); + }); - test('phpunit.Test suite', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'phpunit.xml')); + test("phpunit.Test suite", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "phpunit.xml", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document, { - selection: new vscode.Range(12, 0, 12, 0) // Set the cursor at the line with the Science test suite + selection: new vscode.Range(12, 0, 12, 0), // Set the cursor at the line with the Science test suite }); - const stub = sinon.stub(vscode.window, 'showQuickPick'); - stub.returns(Promise.resolve('Science' as any)); + const stub = sinon.stub(vscode.window, "showQuickPick"); + stub.returns(Promise.resolve("Science" as any)); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.Test'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.Test"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - }); + }); - test('phpunit.TestNearest', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Math/AdditionTest.php')); + test("phpunit.TestNearest", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Math/AdditionTest.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document, { - selection: new vscode.Range(8, 0, 8, 0) // Set the cursor at the first method in the AdditionTest class + selection: new vscode.Range(8, 0, 8, 0), // Set the cursor at the first method in the AdditionTest class }); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.TestNearest'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.TestNearest"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - }); + }); - test('phpunit.TestDirectory', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Math/AdditionTest.php')); + test("phpunit.TestDirectory", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Math/AdditionTest.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.TestDirectory'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.TestDirectory"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - assert.ok(parseInt((task.output).match(/(\d+) \/ \d+ \(100%\)/)![1]) >= 2); + assert.ok(parseInt(task.output.match(/(\d+) \/ \d+ \(100%\)/)![1]) >= 2); }); - - test('phpunit.TestDirectory2', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Science/Weather-1/Weather2Test.php')); + + test("phpunit.TestDirectory2", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Science/Weather-1/Weather2Test.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.TestDirectory2'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.TestDirectory2"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - assert.ok(parseInt((task.output).match(/(\d+) \/ \d+ \(100%\)/)![1]) == 4); + assert.ok(parseInt(task.output.match(/(\d+) \/ \d+ \(100%\)/)![1]) == 4); }); - - test('phpunit.TestDirectory3', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'tests/Science2/Weather-1/Weather/Weather3Test.php')); + + test("phpunit.TestDirectory3", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "tests/Science2/Weather-1/Weather/Weather3Test.php", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.TestDirectory3'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.TestDirectory3"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - assert.ok(parseInt((task.output).match(/(\d+) \/ \d+ \(100%\)/)![1]) == 4); - }); + assert.ok(parseInt(task.output.match(/(\d+) \/ \d+ \(100%\)/)![1]) == 4); + }); - test('phpunit.TestSuite', async () => { - const uri = vscode.Uri.file(path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'phpunit.xml')); + test("phpunit.TestSuite", async () => { + const uri = vscode.Uri.file( + path.resolve( + vscode.workspace.workspaceFolders![0].uri.fsPath, + "phpunit.xml", + ), + ); const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document, { - selection: new vscode.Range(12, 0, 12, 0) // Set the cursor at the line with the Science test suite + selection: new vscode.Range(12, 0, 12, 0), // Set the cursor at the line with the Science test suite }); - const stub = sinon.stub(vscode.window, 'showQuickPick'); - stub.returns(Promise.resolve('Science' as any)); + const stub = sinon.stub(vscode.window, "showQuickPick"); + stub.returns(Promise.resolve("Science" as any)); - const taskOutputPromise = getOnDidEndTaskProcessPromise(myExtensionApi.testRedirectedOutputFile); - const res = await vscode.commands.executeCommand('phpunit.TestSuite'); + const taskOutputPromise = getOnDidEndTaskProcessPromise( + myExtensionApi.testRedirectedOutputFile, + ); + const res = await vscode.commands.executeCommand("phpunit.TestSuite"); const task = await taskOutputPromise; - assert.match(task.output, /PHPUnit .* by Sebastian Bergmann and contributors./); + assert.match( + task.output, + /PHPUnit .* by Sebastian Bergmann and contributors./, + ); assert.equal(task.exitCode, 0); - }); + }); }); diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index bbf171f..f389bec 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -1,16 +1,16 @@ -import * as assert from 'assert'; +import * as assert from "assert"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import * as vscode from 'vscode'; +import * as vscode from "vscode"; // import * as myExtension from '../../extension'; -import path = require('path'); +import path = require("path"); -suite('Extension Test Suite', () => { - vscode.window.showInformationMessage('Start all tests.'); +suite("Extension Test Suite", () => { + vscode.window.showInformationMessage("Start all tests."); - test('Sample test', () => { - assert.strictEqual([1, 2, 3].indexOf(5), -1); - assert.strictEqual([1, 2, 3].indexOf(0), -1); - }); + test("Sample test", () => { + assert.strictEqual([1, 2, 3].indexOf(5), -1); + assert.strictEqual([1, 2, 3].indexOf(0), -1); + }); }); diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts index f16084d..7553b1f 100644 --- a/src/test/suite/index.ts +++ b/src/test/suite/index.ts @@ -1,36 +1,36 @@ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import { glob } from 'glob'; +import * as path from "path"; +import * as Mocha from "mocha"; +import { glob } from "glob"; export async function run(): Promise { - // Create the mocha test - const mocha = new Mocha({ - ui: 'tdd', + // Create the mocha test + const mocha = new Mocha({ + ui: "tdd", timeout: 30000, - reporter: 'mocha-multi-reporters', + reporter: "mocha-multi-reporters", reporterOptions: { - reporterEnabled: 'spec, mocha-junit-reporter', + reporterEnabled: "spec, mocha-junit-reporter", mochaJunitReporterReporterOptions: { - mochaFile: path.resolve(__dirname, '../../../', 'test-results.xml'), + mochaFile: path.resolve(__dirname, "../../../", "test-results.xml"), }, - } - }); - - const testsRoot = path.resolve(__dirname, '..'); + }, + }); + + const testsRoot = path.resolve(__dirname, ".."); - const files = await glob('**/**.test.js', { cwd: testsRoot }); + const files = await glob("**/**.test.js", { cwd: testsRoot }); // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); // Run the mocha test return new Promise((resolve, reject) => { - mocha.run(failures => { - if (failures > 0) { - reject(new Error(`${failures} tests failed.`)); - } else { - resolve(); - } + mocha.run((failures) => { + if (failures > 0) { + reject(new Error(`${failures} tests failed.`)); + } else { + resolve(); + } }); }); } diff --git a/tsconfig.json b/tsconfig.json index 73970bb..90c1da9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,27 +1,20 @@ { - "compilerOptions": { - "module": "commonjs", - "target": "es2020", - "outDir": "out", - "lib": [ - "es2020" - ], - "sourceMap": true, - "strict": true, - "rootDir": "src", - "plugins": [ - { - "name": "typescript-tslint-plugin" - } - ] - }, - "exclude": [ - "node_modules", - ".vscode-test", - "test-resources", - "vscodeJVCoE0" - ], - "typeAcquisition": { - "enable": true - } -} \ No newline at end of file + "compilerOptions": { + "module": "commonjs", + "target": "es2020", + "outDir": "out", + "lib": ["es2020"], + "sourceMap": true, + "strict": true, + "rootDir": "src", + "plugins": [ + { + "name": "typescript-tslint-plugin" + } + ] + }, + "exclude": ["node_modules", ".vscode-test", "test-resources", "vscodeJVCoE0"], + "typeAcquisition": { + "enable": true + } +}