├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── BUG_REPORT.md │ └── FEATURE_REQUEST.md └── workflows │ └── tests.yml ├── .gitignore ├── .vscode └── launch.json ├── .vscodeignore ├── CHANGELOG.md ├── README.md ├── demo.gif ├── icon.png ├── jsconfig.json ├── package-lock.json ├── package.json ├── packaged_releases ├── better-phpunit-1.2.2.vsix └── better-phpunit-1.4.0.vsix ├── src ├── docker-phpunit-command.js ├── extension.js ├── phpunit-command.js ├── remote-phpunit-command.js └── test │ ├── runTest.ts │ └── suite │ ├── extension.test.ts │ ├── index.ts │ ├── pest.test.ts │ └── ssh.test.ts ├── test └── project-stub │ ├── .gitignore │ ├── .php_cs.dist │ ├── .vscode │ └── settings.json │ ├── composer.json │ ├── composer.json.pest │ ├── composer.lock │ ├── phpunit.xml │ ├── sub-directory │ ├── .gitignore │ ├── composer.json │ ├── composer.json.pest │ ├── composer.lock │ ├── phpunit.xml │ └── tests │ │ └── SampleTest.php │ └── tests │ ├── File With Spaces Test.php │ ├── OtherTest.php │ ├── SamplePestTest.php │ └── SampleTest.php ├── tsconfig.json └── vsc-extension-quickstart.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "sourceType": "module" 13 | }, 14 | "rules": { 15 | "no-const-assign": "warn", 16 | "no-this-before-super": "warn", 17 | "no-undef": "warn", 18 | "no-unreachable": "warn", 19 | "no-unused-vars": "warn", 20 | "constructor-super": "warn", 21 | "valid-typeof": "warn" 22 | } 23 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG_REPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | --- 5 | 6 | 7 | 8 | ## What are the steps to reproduce this issue? 9 | 10 | 1. … 11 | 2. … 12 | 3. … 13 | 14 | ## What happens? 15 | … 16 | 17 | ## What were you expecting to happen? 18 | … 19 | 20 | ## Any logs, error output, etc? 21 | … 22 | 23 | ## Any other comments? 24 | … 25 | 26 | ## What versions are you using? 27 | **Operating System:** … 28 | **Package Version:** … 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Request a new feature or enhancement 4 | --- 5 | 6 | 7 | 8 | ## Summary 9 | 10 | 11 | ## Detailed Description 12 | 13 | 14 | ## Possible Implementation Ideas 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | strategy: 6 | matrix: 7 | os: [macos-latest, ubuntu-latest] 8 | runs-on: ${{ matrix.os }} 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v3 12 | - name: Install Node.js 13 | uses: actions/setup-node@v3 14 | with: 15 | node-version: 16.x 16 | - run: npm install 17 | - run: xvfb-run -a npm test 18 | if: runner.os == 'Linux' 19 | - run: npm test 20 | if: runner.os != 'Linux' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode-test/ 3 | .vsix 4 | .DS_Store 5 | out 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "${workspaceFolder}/test/project-stub", 15 | "--extensionDevelopmentPath=${workspaceFolder}", 16 | ] 17 | }, 18 | { 19 | "name": "Extension Tests", 20 | "type": "extensionHost", 21 | "request": "launch", 22 | "runtimeExecutable": "${execPath}", 23 | "args": [ 24 | "${workspaceFolder}/test/project-stub", 25 | "--extensionDevelopmentPath=${workspaceFolder}", 26 | "--extensionTestsPath=${workspaceFolder}/test", 27 | ], 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | test/** 4 | .gitignore 5 | jsconfig.json 6 | vsc-extension-quickstart.md 7 | .eslintrc.json 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to the "better-phpunit" extension will be documented in this file. 3 | 4 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 5 | 6 | ## [Unreleased] 7 | - Initial release -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Better PHPUnit 2 | 3 | Better PHPUnit is the most popular, cleanest, and fastest PHPUnit runner for VS Code. 4 | 5 | ![Demo GIF](demo.gif) 6 | 7 | ## Run a test method: 8 | - Place your cursor in/on the method you want to run 9 | - Open the command menu: `cmd+shift+p` 10 | - Select: `Better PHPUnit: run` 11 | 12 | ## Run a test file: 13 | - Open the command menu: `cmd+shift+p` 14 | - Select: `Better PHPUnit: run-file` 15 | 16 | ## Run the entire suite: 17 | - Open the command menu: `cmd+shift+p` 18 | - Select: `Better PHPUnit: run suite` 19 | 20 | ## Run the previous test: 21 | - Open the command menu: `cmd+shift+p` 22 | - Select: `Better PHPUnit: run previous` 23 | 24 | ## Features: 25 | - Color output! 26 | - Run individual methods by placing your cursor anywhere in/on the method 27 | - Test failures are displayed in the "Problems" panel for quick access 28 | 29 | > Note: this plugin registers "tasks" to run phpunit, not a command like other extensions. This makes it possible to leverage the problem output and color terminal. 30 | 31 | Keybindings: 32 | ``` 33 | { 34 | "key": "cmd+k cmd+r", 35 | "command": "better-phpunit.run" 36 | }, 37 | { 38 | "key": "cmd+k cmd+f", 39 | "command": "better-phpunit.run-file" 40 | }, 41 | { 42 | "key": "cmd+k cmd+p", 43 | "command": "better-phpunit.run-previous" 44 | } 45 | ``` 46 | 47 | Config: 48 | ``` 49 | { 50 | "better-phpunit.commandSuffix": null, // This string will be appended to the phpunit command, it's a great place to add flags like '--stop-on-failure' 51 | "better-phpunit.phpunitBinary": null, // A custom phpunit binary. Ex: 'phpunit', '/usr/local/bin/phpunit' 52 | "better-phpunit.suiteSuffix": null // Specify options to appended only to the 'run suite' command, for example add options like '--testsuite unit' or '--coverage --coverage-xml'. 53 | } 54 | ``` 55 | 56 | Running tests over ssh (For VMs like Laravel Homestead): 57 | ``` 58 | { 59 | "better-phpunit.ssh.enable": true, 60 | "better-phpunit.ssh.paths": { 61 | "/your/local/path": "/your/remote/path" 62 | }, 63 | "better-phpunit.ssh.user": "user", 64 | "better-phpunit.ssh.host": "host", 65 | "better-phpunit.ssh.port": "22", 66 | "better-phpunit.ssh.binary": "putty -ssh" 67 | } 68 | ``` 69 | 70 | Running tests in already running Docker containers: 71 | ``` 72 | { 73 | "better-phpunit.docker.enable": true, 74 | "better-phpunit.docker.command": "docker exec container-name", 75 | "better-phpunit.docker.paths": { 76 | "/your/local/path": "/your/remote/path" 77 | }, 78 | } 79 | ``` 80 | 81 | Running tests with Docker Compose, starting up a service and removing the container when finished: 82 | ``` 83 | { 84 | "better-phpunit.docker.enable": true, 85 | "better-phpunit.docker.command": "docker-compose run --rm service-name", 86 | "better-phpunit.docker.paths": { 87 | "/your/local/path": "/your/remote/path" 88 | }, 89 | } 90 | ``` 91 | 92 | Running tests with Laravel Sail: 93 | ``` 94 | { 95 | "better-phpunit.docker.enable": true, 96 | "better-phpunit.docker.command": "docker compose exec -u sail laravel.test", 97 | "better-phpunit.docker.paths": { 98 | "/your/local/path": "/var/www/html" 99 | }, 100 | "better-phpunit.phpunitBinary": "php artisan test", 101 | } 102 | ``` 103 | 104 | **Note:** 105 | For running Docker over a SSH session just use both options _ssh.enable_ and _docker.enable_ combined. 106 | 107 | ## Wish List: 108 | - Handling PHP fatal and parser errors 109 | - A sidebar panel for managing errors 110 | - Re-run failures 111 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebporzio/better-phpunit/b9f58560684cdd06f90676d1ee2cc250d6c0ea85/demo.gif -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebporzio/better-phpunit/b9f58560684cdd06f90676d1ee2cc250d6c0ea85/icon.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "lib": [ 6 | "es6" 7 | ] 8 | }, 9 | "exclude": [ 10 | "node_modules" 11 | ] 12 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "better-phpunit", 3 | "displayName": "Better PHPUnit", 4 | "description": "A better PHPUnit test runner", 5 | "version": "1.6.2", 6 | "publisher": "calebporzio", 7 | "engines": { 8 | "vscode": "^1.74.0" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/calebporzio/better-phpunit.git" 13 | }, 14 | "icon": "icon.png", 15 | "categories": [ 16 | "Other" 17 | ], 18 | "activationEvents": [ 19 | "onCommand:better-phpunit.run", 20 | "onCommand:better-phpunit.run-file", 21 | "onCommand:better-phpunit.run-suite" 22 | ], 23 | "main": "./src/extension", 24 | "contributes": { 25 | "commands": [ 26 | { 27 | "command": "better-phpunit.run", 28 | "title": "Better PHPUnit: run" 29 | }, 30 | { 31 | "command": "better-phpunit.run-file", 32 | "title": "Better PHPUnit: run file" 33 | }, 34 | { 35 | "command": "better-phpunit.run-suite", 36 | "title": "Better PHPUnit: run suite" 37 | }, 38 | { 39 | "command": "better-phpunit.run-previous", 40 | "title": "Better PHPUnit: run previous" 41 | } 42 | ], 43 | "keybindings": [ 44 | { 45 | "key": "cmd+k cmd+r", 46 | "command": "better-phpunit.run", 47 | "when": "editorLangId == php" 48 | }, 49 | { 50 | "key": "cmd+k cmd+f", 51 | "command": "better-phpunit.run-file", 52 | "when": "editorLangId == php" 53 | }, 54 | { 55 | "key": "cmd+k cmd+p", 56 | "command": "better-phpunit.run-previous", 57 | "when": "editorLangId == php" 58 | } 59 | ], 60 | "configuration": { 61 | "title": "Better PHPUnit configuration", 62 | "properties": { 63 | "better-phpunit.commandSuffix": { 64 | "type": [ 65 | "string", 66 | "null" 67 | ], 68 | "default": null, 69 | "description": "This string will be appended to the phpunit command, it's a great place to add flags like '--stop-on-failure'" 70 | }, 71 | "better-phpunit.phpunitBinary": { 72 | "type": [ 73 | "string", 74 | "null" 75 | ], 76 | "default": null, 77 | "description": "A custom phpunit binary. Ex: 'phpunit', '/usr/local/bin/phpunit'" 78 | }, 79 | "better-phpunit.pestBinary": { 80 | "type": [ 81 | "string", 82 | "null" 83 | ], 84 | "default": null, 85 | "description": "A custom Pest binary. Ex: 'pest', '/usr/local/bin/pest'" 86 | }, 87 | "better-phpunit.xmlConfigFilepath": { 88 | "type": [ 89 | "string", 90 | "null" 91 | ], 92 | "default": null, 93 | "description": "Absolute path for the PHPUnit XML configuration file" 94 | }, 95 | "better-phpunit.suiteSuffix": { 96 | "type": [ 97 | "string", 98 | "null" 99 | ], 100 | "default": null, 101 | "description": "Specify options to appended only to the 'run suite' command, for example add options like '--testsuite unit' or '--coverage --coverage-xml'" 102 | }, 103 | "better-phpunit.ssh.enable": { 104 | "type": "boolean", 105 | "default": false, 106 | "description": "Run tests over SSH" 107 | }, 108 | "better-phpunit.ssh.user": { 109 | "type": [ 110 | "string", 111 | "null" 112 | ], 113 | "default": null, 114 | "description": "The user to connect as when running test via SSH" 115 | }, 116 | "better-phpunit.ssh.host": { 117 | "type": [ 118 | "string", 119 | "null" 120 | ], 121 | "default": null, 122 | "description": "The hostname to use when running tests via SSH" 123 | }, 124 | "better-phpunit.ssh.port": { 125 | "type": [ 126 | "integer" 127 | ], 128 | "default": 22, 129 | "description": "The port to use when running tests via SSH. Deprecated, set better-phpunit.options to '-p[port]' on Linux/Mac, and '-P [port]' on Windows." 130 | }, 131 | "better-phpunit.ssh.paths": { 132 | "type": "object", 133 | "default": {}, 134 | "description": "The SSH path map. Keys are local (host) paths and values are remote (guest) paths." 135 | }, 136 | "better-phpunit.ssh.binary": { 137 | "type": [ 138 | "string", 139 | "null" 140 | ], 141 | "default": null, 142 | "description": "The path (and flags) to an SSH-compatible binary. If null it will use SSH on *nix and Putty on Windows." 143 | }, 144 | "better-phpunit.ssh.disableAllOptions": { 145 | "type": "boolean", 146 | "default": false, 147 | "description": "Do not include any config options in SSH command." 148 | }, 149 | "better-phpunit.ssh.options": { 150 | "type": [ 151 | "string", 152 | "null" 153 | ], 154 | "default": null, 155 | "description": "Additional command line options to pass to ssh/putty/plink" 156 | }, 157 | "better-phpunit.docker.enable": { 158 | "type": "boolean", 159 | "default": false, 160 | "description": "Run tests within a Docker container" 161 | }, 162 | "better-phpunit.docker.command": { 163 | "type": [ 164 | "string", 165 | "null" 166 | ], 167 | "default": null, 168 | "description": "The Docker command to execute a container. If null, an error will be thrown during execution." 169 | }, 170 | "better-phpunit.docker.paths": { 171 | "type": "object", 172 | "default": {}, 173 | "description": "The docker path map. Keys are local (host) paths and values are remote (container) paths." 174 | } 175 | } 176 | }, 177 | "problemMatchers": [ 178 | { 179 | "name": "phpunit", 180 | "owner": "php", 181 | "fileLocation": "absolute", 182 | "pattern": [ 183 | { 184 | "regexp": "^\\d+\\)\\s.*$" 185 | }, 186 | { 187 | "regexp": "^(.*)$", 188 | "message": 1 189 | }, 190 | { 191 | "regexp": "^(.*):(\\d+)$", 192 | "file": 1, 193 | "location": 2 194 | } 195 | ] 196 | } 197 | ], 198 | "taskDefinitions": [ 199 | { 200 | "type": "phpunit", 201 | "required": [ 202 | "task" 203 | ], 204 | "properties": { 205 | "task": { 206 | "type": "string", 207 | "description": "The task to execute" 208 | } 209 | } 210 | } 211 | ] 212 | }, 213 | "scripts": { 214 | "vscode:prepublish": "npm run compile", 215 | "compile": "tsc -p ./", 216 | "watch": "tsc -watch -p ./", 217 | "pretest": "npm run compile", 218 | "test": "node ./out/test/runTest.js" 219 | }, 220 | "devDependencies": { 221 | "@types/glob": "^7.1.1", 222 | "@types/mocha": "^10.0.1", 223 | "@types/node": "^20.8.4", 224 | "@types/vscode": "^1.74.0", 225 | "@typescript-eslint/eslint-plugin": "^6.7.0", 226 | "@typescript-eslint/parser": "^6.7.0", 227 | "@vscode/test-electron": "^2.3.0", 228 | "eslint": "^8.26.0", 229 | "glob": "^7.1.4", 230 | "mocha": "^10.2.0", 231 | "source-map-support": "^0.5.12", 232 | "typescript": "^5.2.2" 233 | }, 234 | "dependencies": { 235 | "find-up": "^2.1.0" 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /packaged_releases/better-phpunit-1.2.2.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebporzio/better-phpunit/b9f58560684cdd06f90676d1ee2cc250d6c0ea85/packaged_releases/better-phpunit-1.2.2.vsix -------------------------------------------------------------------------------- /packaged_releases/better-phpunit-1.4.0.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebporzio/better-phpunit/b9f58560684cdd06f90676d1ee2cc250d6c0ea85/packaged_releases/better-phpunit-1.4.0.vsix -------------------------------------------------------------------------------- /src/docker-phpunit-command.js: -------------------------------------------------------------------------------- 1 | const vscode = require('vscode'); 2 | const RemotePhpUnitCommand = require('./remote-phpunit-command'); 3 | 4 | module.exports = class DockerPhpUnitCommand extends RemotePhpUnitCommand { 5 | get paths() { 6 | return this.config.get("docker.paths"); 7 | } 8 | 9 | get dockerCommand() { 10 | if (this.config.get("docker.command")) { 11 | return this.config.get("docker.command"); 12 | } 13 | 14 | const msg = "No better-phpunit.docker.command was specified in the settings"; 15 | vscode.window.showErrorMessage(msg); 16 | 17 | throw msg; 18 | } 19 | 20 | wrapCommand(command) { 21 | if (vscode.workspace.getConfiguration("better-phpunit").get("ssh.enable")) { 22 | return super.wrapCommand(`${this.dockerCommand} ${command}`); 23 | } 24 | return `${this.dockerCommand} ${command}`; 25 | } 26 | } -------------------------------------------------------------------------------- /src/extension.js: -------------------------------------------------------------------------------- 1 | const vscode = require('vscode'); 2 | const PhpUnitCommand = require('./phpunit-command'); 3 | const RemotePhpUnitCommand = require('./remote-phpunit-command.js'); 4 | const DockerPhpUnitCommand = require('./docker-phpunit-command.js'); 5 | 6 | var globalCommand; 7 | 8 | module.exports.activate = function (context) { 9 | let disposables = []; 10 | 11 | disposables.push(vscode.commands.registerCommand('better-phpunit.run', async () => { 12 | let command; 13 | 14 | if (vscode.workspace.getConfiguration("better-phpunit").get("docker.enable")) { 15 | command = new DockerPhpUnitCommand; 16 | } else if (vscode.workspace.getConfiguration("better-phpunit").get("ssh.enable")) { 17 | command = new RemotePhpUnitCommand; 18 | } else { 19 | command = new PhpUnitCommand; 20 | } 21 | 22 | await runCommand(command); 23 | })); 24 | 25 | disposables.push(vscode.commands.registerCommand('better-phpunit.run-file', async () => { 26 | let command; 27 | 28 | if (vscode.workspace.getConfiguration("better-phpunit").get("docker.enable")) { 29 | command = new DockerPhpUnitCommand({ runFile: true }); 30 | } else if (vscode.workspace.getConfiguration("better-phpunit").get("ssh.enable")) { 31 | command = new RemotePhpUnitCommand({ runFile: true }); 32 | } else { 33 | command = new PhpUnitCommand({ runFile: true }); 34 | } 35 | 36 | await runCommand(command); 37 | })); 38 | 39 | disposables.push(vscode.commands.registerCommand('better-phpunit.run-suite', async () => { 40 | let command; 41 | 42 | if (vscode.workspace.getConfiguration("better-phpunit").get("docker.enable")) { 43 | command = new DockerPhpUnitCommand({ runFullSuite: true }); 44 | } else if (vscode.workspace.getConfiguration("better-phpunit").get("ssh.enable")) { 45 | command = new RemotePhpUnitCommand({ runFullSuite: true }); 46 | } else { 47 | command = new PhpUnitCommand({ runFullSuite: true }); 48 | } 49 | 50 | await runCommand(command); 51 | })); 52 | 53 | disposables.push(vscode.commands.registerCommand('better-phpunit.run-previous', async () => { 54 | await runPreviousCommand(); 55 | })); 56 | 57 | disposables.push(vscode.tasks.registerTaskProvider('phpunit', { 58 | provideTasks: () => { 59 | return [new vscode.Task( 60 | { type: "phpunit", task: "run" }, 61 | 2, 62 | "run", 63 | 'phpunit', 64 | new vscode.ShellExecution(globalCommand.output), 65 | '$phpunit' 66 | )]; 67 | } 68 | })); 69 | 70 | context.subscriptions.push(disposables); 71 | } 72 | 73 | async function runCommand(command) { 74 | setGlobalCommandInstance(command); 75 | 76 | vscode.window.activeTextEditor 77 | || vscode.window.showErrorMessage('Better PHPUnit: open a file to run this command'); 78 | 79 | await vscode.commands.executeCommand('workbench.action.terminal.clear'); 80 | await vscode.commands.executeCommand('workbench.action.tasks.runTask', 'phpunit: run'); 81 | } 82 | 83 | async function runPreviousCommand() { 84 | await vscode.commands.executeCommand('workbench.action.terminal.clear'); 85 | await vscode.commands.executeCommand('workbench.action.tasks.runTask', 'phpunit: run'); 86 | } 87 | 88 | function setGlobalCommandInstance(commandInstance) { 89 | // Store this object globally for the provideTasks, "run-previous", and for tests to assert against. 90 | globalCommand = commandInstance; 91 | } 92 | 93 | // This method is exposed for testing purposes. 94 | module.exports.getGlobalCommandInstance = function () { 95 | return globalCommand; 96 | } 97 | -------------------------------------------------------------------------------- /src/phpunit-command.js: -------------------------------------------------------------------------------- 1 | const findUp = require('find-up'); 2 | const vscode = require('vscode'); 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | 6 | module.exports = class PhpUnitCommand { 7 | constructor(options) { 8 | this.runFullSuite = options !== undefined 9 | ? options.runFullSuite 10 | : false; 11 | 12 | this.runFile = options !== undefined 13 | ? options.runFile 14 | : false; 15 | 16 | this.lastOutput; 17 | this.isPest = this._isPest(); 18 | } 19 | 20 | get output() { 21 | if (this.lastOutput) { 22 | return this.lastOutput; 23 | } 24 | 25 | let suiteSuffix = vscode.workspace.getConfiguration('better-phpunit').get('suiteSuffix'); 26 | suiteSuffix = suiteSuffix ? ' '.concat(suiteSuffix) : ''; 27 | 28 | if (this.runFullSuite) { 29 | this.lastOutput = `${this.binary}${suiteSuffix}${this.suffix}` 30 | } else if (this.runFile) { 31 | this.lastOutput = `${this.binary} ${this.file}${this.configuration}${this.suffix}`; 32 | } else { 33 | this.lastOutput = `${this.binary} ${this.file}${this.filter}${this.configuration}${this.suffix}`; 34 | } 35 | 36 | return this.lastOutput; 37 | } 38 | 39 | get file() { 40 | return this._normalizePath(vscode.window.activeTextEditor.document.fileName); 41 | } 42 | 43 | get filter() { 44 | if (this.isPest) { 45 | return this.method ? ` --filter ${this.method}` : ''; 46 | } 47 | 48 | return process.platform === "win32" 49 | ? (this.method ? ` --filter '^.*::${this.method}'` : '') 50 | : (this.method ? ` --filter '^.*::${this.method}( .*)?$'` : ''); 51 | } 52 | 53 | get configuration() { 54 | let configFilepath = vscode.workspace.getConfiguration('better-phpunit').get('xmlConfigFilepath'); 55 | if (configFilepath !== null) { 56 | return ` --configuration ${configFilepath}`; 57 | } 58 | return this.subDirectory 59 | ? ` --configuration ${this._normalizePath(path.join(this.subDirectory, 'phpunit.xml'))}` 60 | : ''; 61 | } 62 | 63 | get suffix() { 64 | let suffix = vscode.workspace.getConfiguration('better-phpunit').get('commandSuffix'); 65 | 66 | return suffix ? ' ' + suffix : ''; // Add a space before the suffix. 67 | } 68 | 69 | get windowsSuffix() { 70 | return process.platform === "win32" 71 | ? '.bat' 72 | : ''; 73 | } 74 | 75 | get binary() { 76 | const binaryKey = this.isPest ? 'pestBinary' : 'phpunitBinary'; 77 | 78 | if (vscode.workspace.getConfiguration('better-phpunit').get(binaryKey)) { 79 | return vscode.workspace.getConfiguration('better-phpunit').get(binaryKey) 80 | } 81 | 82 | const binary = this.isPest ? 'pest' : 'phpunit'; 83 | 84 | return this.subDirectory 85 | ? this._normalizePath(path.join(this.subDirectory, 'vendor', 'bin', binary+this.windowsSuffix)) 86 | : this._normalizePath(path.join(vscode.workspace.rootPath, 'vendor', 'bin', binary+this.windowsSuffix)); 87 | } 88 | 89 | get subDirectory() { 90 | // find the closest phpunit.xml file in the project (for projects with multiple "vendor/bin/phpunit"s). 91 | let phpunitDotXml = findUp.sync(['phpunit.xml', 'phpunit.xml.dist'], { cwd: vscode.window.activeTextEditor.document.fileName }); 92 | 93 | return path.dirname(phpunitDotXml) !== vscode.workspace.rootPath 94 | ? path.dirname(phpunitDotXml) 95 | : null; 96 | } 97 | 98 | get method() { 99 | let line = vscode.window.activeTextEditor.selection.active.line; 100 | let method; 101 | 102 | while (line > 0) { 103 | const lineText = vscode.window.activeTextEditor.document.lineAt(line).text; 104 | const match = this.isPest ? 105 | lineText.match(/^\s*(?:it|test)\(([^,)]+)/m) : 106 | lineText.match(/^\s*(?:public|private|protected)?\s*function\s*(\w+)\s*\(.*$/); 107 | 108 | if (match) { 109 | method = match[1]; 110 | break; 111 | } 112 | line = line - 1; 113 | } 114 | 115 | return method; 116 | } 117 | 118 | _isPest() { 119 | const start = Date.now(); 120 | const composerJson = findUp.sync('composer.json', { cwd: vscode.window.activeTextEditor.document.fileName }); 121 | 122 | if (!fs.existsSync(composerJson)) { 123 | return false; 124 | } 125 | 126 | const isPest = fs.readFileSync(composerJson, 'utf8').includes('"pestphp/pest"'); 127 | const end = Date.now(); 128 | console.log(`Checking for Pest: ${end - start}ms`) 129 | 130 | return isPest; 131 | } 132 | 133 | _normalizePath(path) { 134 | return path 135 | .replace(/\\/g, '/') // Convert backslashes from windows paths to forward slashes, otherwise the shell will ignore them. 136 | .replace(/ /g, '\\ '); // Escape spaces. 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/remote-phpunit-command.js: -------------------------------------------------------------------------------- 1 | const vscode = require('vscode'); 2 | const PhpUnitCommand = require('./phpunit-command'); 3 | const path = require('path'); 4 | const os = require('os'); 5 | 6 | module.exports = class RemotePhpUnitCommand extends PhpUnitCommand { 7 | constructor(options) { 8 | super(options); 9 | 10 | this.config = vscode.workspace.getConfiguration("better-phpunit"); 11 | } 12 | 13 | get file() { 14 | return this.remapLocalPath(super.file); 15 | } 16 | 17 | get binary() { 18 | return this.remapLocalPath(super.binary) 19 | } 20 | 21 | get output() { 22 | return this.wrapCommand(super.output); 23 | } 24 | 25 | get configuration() { 26 | return this.subDirectory 27 | ? ' --configuration ' + this.remapLocalPath(this._normalizePath(path.join(this.subDirectory, 'phpunit.xml'))) 28 | : ''; 29 | } 30 | 31 | get paths() { 32 | return this.config.get("ssh.paths"); 33 | } 34 | 35 | get sshBinary() { 36 | if (this.config.get("ssh.binary")) { 37 | return this.config.get("ssh.binary"); 38 | } 39 | 40 | return "ssh"; 41 | } 42 | 43 | remapLocalPath(actualPath) { 44 | for (const [localPath, remotePath] of Object.entries(this.paths)) { 45 | const expandedLocalPath = localPath.replace(/^~/, os.homedir()); 46 | if (actualPath.startsWith(expandedLocalPath)) { 47 | return actualPath.replace(expandedLocalPath, remotePath); 48 | } 49 | } 50 | 51 | return actualPath; 52 | } 53 | 54 | wrapCommand(command) { 55 | const user = this.config.get("ssh.user"); 56 | const port = this.config.get("ssh.port"); 57 | const host = this.config.get("ssh.host"); 58 | let options = this.config.get("ssh.options"); 59 | let disableOptions = this.config.get("ssh.disableAllOptions"); 60 | let optionsString = ''; 61 | 62 | if (!disableOptions) { 63 | if (!options) { 64 | options = `-tt -p${port}`; 65 | } 66 | optionsString = options + ` ${user}@${host} `; 67 | } 68 | 69 | return `${this.sshBinary} ${optionsString}"${command}"`; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from '@vscode/test-electron'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to the extension test script 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | const testWorkspace = path.resolve(__dirname, '../../test/project-stub'); 15 | 16 | // Download VS Code, unzip it and run the integration test 17 | await runTests({ extensionDevelopmentPath, extensionTestsPath, launchArgs: [testWorkspace], }); 18 | } catch (err) { 19 | console.error('Failed to run tests'); 20 | process.exit(1); 21 | } 22 | } 23 | 24 | main(); -------------------------------------------------------------------------------- /src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { beforeEach, afterEach } from 'mocha'; 3 | import * as path from 'path'; 4 | 5 | const vscode = require('vscode'); 6 | const extension = require('../../../src/extension'); 7 | 8 | const waitToAssertInSeconds = 5; 9 | 10 | // This is a little helper function to promisify setTimeout, so we can "await" setTimeout. 11 | function timeout(seconds: any, callback: any) { 12 | return new Promise(resolve => { 13 | setTimeout(() => { 14 | callback(); 15 | resolve(''); 16 | }, seconds * waitToAssertInSeconds); 17 | }); 18 | } 19 | 20 | suite("Better PHPUnit Test Suite", function () { 21 | beforeEach(async () => { 22 | // Reset the test/project-stub/.vscode/settings.json settings for each test. 23 | // This allows us to test config options in tests and not harm other tests. 24 | await vscode.workspace.getConfiguration('better-phpunit').update('commandSuffix', null); 25 | await vscode.workspace.getConfiguration('better-phpunit').update('phpunitBinary', null); 26 | await vscode.workspace.getConfiguration('better-phpunit').update('pestBinary', null); 27 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 28 | await vscode.workspace.getConfiguration("better-phpunit").update("xmlConfigFilepath", null); 29 | await vscode.workspace.getConfiguration("better-phpunit").update("suiteSuffix", null); 30 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", false); 31 | }); 32 | 33 | afterEach(async () => { 34 | // Reset the test/project-stub/.vscode/settings.json settings for each test. 35 | // This allows us to test config options in tests and not harm other tests. 36 | await vscode.workspace.getConfiguration('better-phpunit').update('commandSuffix', null); 37 | await vscode.workspace.getConfiguration('better-phpunit').update('phpunitBinary', null); 38 | await vscode.workspace.getConfiguration('better-phpunit').update('pestBinary', null); 39 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 40 | await vscode.workspace.getConfiguration("better-phpunit").update("xmlConfigFilepath", null); 41 | await vscode.workspace.getConfiguration("better-phpunit").update("suiteSuffix", null); 42 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", false); 43 | }); 44 | 45 | test("Run file outside of method", async () => { 46 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 47 | await vscode.window.showTextDocument(document); 48 | await vscode.commands.executeCommand('better-phpunit.run'); 49 | 50 | await timeout(waitToAssertInSeconds, () => { 51 | assert.ok(extension.getGlobalCommandInstance().method === undefined); 52 | }); 53 | }); 54 | 55 | test("Run file", async () => { 56 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 57 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 58 | await vscode.commands.executeCommand('better-phpunit.run-file'); 59 | 60 | await timeout(waitToAssertInSeconds, () => { 61 | assert.equal( 62 | extension.getGlobalCommandInstance().output, 63 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit') + ' ' + path.join(vscode.workspace.rootPath, '/tests/SampleTest.php') 64 | ); 65 | }); 66 | }); 67 | 68 | test("Run from within first method", async () => { 69 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 70 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 71 | await vscode.commands.executeCommand('better-phpunit.run'); 72 | 73 | await timeout(waitToAssertInSeconds, () => { 74 | assert.equal( 75 | extension.getGlobalCommandInstance().method, 76 | 'test_first' 77 | ); 78 | }); 79 | }); 80 | 81 | test("Run from within second method", async () => { 82 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 83 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(12, 0, 12, 0) }); 84 | await vscode.commands.executeCommand('better-phpunit.run'); 85 | 86 | await timeout(waitToAssertInSeconds, () => { 87 | assert.equal( 88 | extension.getGlobalCommandInstance().method, 89 | 'test_second' 90 | ); 91 | }); 92 | }); 93 | 94 | test("Detect filename", async () => { 95 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 96 | await vscode.window.showTextDocument(document); 97 | await vscode.commands.executeCommand('better-phpunit.run'); 98 | 99 | await timeout(waitToAssertInSeconds, () => { 100 | assert.equal( 101 | extension.getGlobalCommandInstance().file, 102 | path.join(vscode.workspace.rootPath, '/tests/SampleTest.php') 103 | ); 104 | }); 105 | }); 106 | 107 | test("Detect filename with a space", async () => { 108 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'File With Spaces Test.php')); 109 | await vscode.window.showTextDocument(document); 110 | await vscode.commands.executeCommand('better-phpunit.run'); 111 | 112 | await timeout(waitToAssertInSeconds, () => { 113 | assert.equal( 114 | extension.getGlobalCommandInstance().file.replace(/\\/g, 'XX'), 115 | path.join(vscode.workspace.rootPath, '/tests/FileXX WithXX SpacesXX Test.php') 116 | ); 117 | }); 118 | }); 119 | 120 | test("Detect executable", async () => { 121 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 122 | await vscode.window.showTextDocument(document); 123 | await vscode.commands.executeCommand('better-phpunit.run'); 124 | 125 | await timeout(waitToAssertInSeconds, () => { 126 | assert.equal( 127 | extension.getGlobalCommandInstance().binary, 128 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit') 129 | ); 130 | }); 131 | }); 132 | 133 | test("Detect executable in sub-directory", async () => { 134 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'sub-directory', 'tests', 'SampleTest.php')); 135 | await vscode.window.showTextDocument(document); 136 | await vscode.commands.executeCommand('better-phpunit.run'); 137 | 138 | await timeout(waitToAssertInSeconds, () => { 139 | assert.equal( 140 | extension.getGlobalCommandInstance().binary, 141 | path.join(vscode.workspace.rootPath, '/sub-directory/vendor/bin/phpunit') 142 | ); 143 | }); 144 | }); 145 | 146 | test("Detect configuration in sub-directory", async () => { 147 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'sub-directory', 'tests', 'SampleTest.php')); 148 | await vscode.window.showTextDocument(document); 149 | await vscode.commands.executeCommand('better-phpunit.run'); 150 | 151 | await timeout(waitToAssertInSeconds, () => { 152 | assert.equal( 153 | extension.getGlobalCommandInstance().configuration, 154 | ` --configuration ${path.join(vscode.workspace.rootPath, '/sub-directory/phpunit.xml')}` 155 | ); 156 | }); 157 | }); 158 | 159 | test("Uses configuration found in path supplied in settings", async () => { 160 | await vscode.workspace.getConfiguration('better-phpunit').update('xmlConfigFilepath', '/var/log/phpunit.xml'); 161 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'sub-directory', 'tests', 'SampleTest.php')); 162 | await vscode.window.showTextDocument(document); 163 | await vscode.commands.executeCommand('better-phpunit.run'); 164 | 165 | await timeout(waitToAssertInSeconds, () => { 166 | assert.equal( 167 | extension.getGlobalCommandInstance().configuration, 168 | ` --configuration /var/log/phpunit.xml` 169 | ); 170 | }); 171 | }); 172 | 173 | test("Check full command", async () => { 174 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 175 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 176 | await vscode.commands.executeCommand('better-phpunit.run'); 177 | 178 | await timeout(waitToAssertInSeconds, () => { 179 | assert.equal( 180 | extension.getGlobalCommandInstance().output, 181 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit ') + path.join(vscode.workspace.rootPath, '/tests/SampleTest.php') + " --filter '^.*::test_first( .*)?$'" 182 | ); 183 | }); 184 | }); 185 | 186 | test("Run previous", async () => { 187 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'OtherTest.php')); 188 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(12, 0, 12, 0) }); 189 | await vscode.commands.executeCommand('better-phpunit.run-previous'); 190 | 191 | await timeout(waitToAssertInSeconds, () => { 192 | assert.equal( 193 | extension.getGlobalCommandInstance().output, 194 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit ') + path.join(vscode.workspace.rootPath, '/tests/SampleTest.php') + " --filter '^.*::test_first( .*)?$'" 195 | ); 196 | }); 197 | }); 198 | 199 | test("Run entire suite", async () => { 200 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 201 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 202 | await vscode.commands.executeCommand('better-phpunit.run-suite') 203 | 204 | await timeout(waitToAssertInSeconds, () => { 205 | assert.equal( 206 | extension.getGlobalCommandInstance().output, 207 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit') 208 | ); 209 | }); 210 | }); 211 | 212 | test("Run entire suite with specified options", async () => { 213 | await vscode.workspace.getConfiguration('better-phpunit').update('suiteSuffix', '--testsuite unit --coverage'); 214 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 215 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 216 | await vscode.commands.executeCommand('better-phpunit.run-suite'); 217 | 218 | await timeout(waitToAssertInSeconds, () => { 219 | assert.equal( 220 | extension.getGlobalCommandInstance().output, 221 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit') + ' --testsuite unit --coverage' 222 | ); 223 | }); 224 | }); 225 | 226 | test("Run with commandSuffix config", async () => { 227 | await vscode.workspace.getConfiguration('better-phpunit').update('commandSuffix', '--foo=bar'); 228 | 229 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 230 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 231 | await vscode.commands.executeCommand('better-phpunit.run-suite') 232 | 233 | await timeout(waitToAssertInSeconds, () => { 234 | assert.equal( 235 | extension.getGlobalCommandInstance().output, 236 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit') + ' --foo=bar' 237 | ); 238 | }); 239 | }); 240 | 241 | test("Run with phpunitBinary config", async () => { 242 | await vscode.workspace.getConfiguration('better-phpunit').update('phpunitBinary', 'vendor/foo/bar'); 243 | 244 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 245 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 246 | await vscode.commands.executeCommand('better-phpunit.run-suite') 247 | 248 | await timeout(waitToAssertInSeconds, () => { 249 | assert.equal( 250 | extension.getGlobalCommandInstance().output, 251 | "vendor/foo/bar" 252 | ); 253 | }); 254 | }); 255 | }); 256 | -------------------------------------------------------------------------------- /src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as Mocha from 'mocha'; 3 | import * as glob from 'glob'; 4 | 5 | export function run(): Promise { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd' 9 | }); 10 | 11 | const testsRoot = path.resolve(__dirname, '..'); 12 | 13 | return new Promise((c, e) => { 14 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 15 | if (err) { 16 | return e(err); 17 | } 18 | 19 | // Add files to the test suite 20 | files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); 21 | 22 | try { 23 | // Run the mocha test 24 | mocha.run(failures => { 25 | if (failures > 0) { 26 | e(new Error(`${failures} tests failed.`)); 27 | } else { 28 | c(); 29 | } 30 | }); 31 | } catch (err) { 32 | console.error(err); 33 | e(err); 34 | } 35 | }); 36 | }); 37 | } -------------------------------------------------------------------------------- /src/test/suite/pest.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { beforeEach, afterEach, before, after } from 'mocha'; 3 | import * as path from 'path'; 4 | import * as fs from 'fs'; 5 | 6 | const vscode = require('vscode'); 7 | const extension = require('../../../src/extension'); 8 | 9 | const waitToAssertInSeconds = 5; 10 | 11 | // This is a little helper function to promisify setTimeout, so we can "await" setTimeout. 12 | function timeout(seconds: any, callback: any) { 13 | return new Promise(resolve => { 14 | setTimeout(() => { 15 | callback(); 16 | resolve(''); 17 | }, seconds * waitToAssertInSeconds); 18 | }); 19 | } 20 | 21 | suite("Better PHPUnit Test Suite", function () { 22 | before(async () => { 23 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'composer.json.phpunit'))); 24 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json.phpunit'))); 25 | 26 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json.pest')), path.join(path.join(vscode.workspace.rootPath, 'composer.json'))); 27 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json.pest')), path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json'))); 28 | }); 29 | 30 | beforeEach(async () => { 31 | // Reset the test/project-stub/.vscode/settings.json settings for each test. 32 | // This allows us to test config options in tests and not harm other tests. 33 | await vscode.workspace.getConfiguration('better-phpunit').update('commandSuffix', null); 34 | await vscode.workspace.getConfiguration('better-phpunit').update('phpunitBinary', null); 35 | await vscode.workspace.getConfiguration('better-phpunit').update('pestBinary', null); 36 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 37 | await vscode.workspace.getConfiguration("better-phpunit").update("xmlConfigFilepath", null); 38 | await vscode.workspace.getConfiguration("better-phpunit").update("suiteSuffix", null); 39 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", false); 40 | }); 41 | 42 | after(async () => { 43 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'composer.json.pest'))); 44 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json.pest'))); 45 | 46 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json.phpunit')), path.join(path.join(vscode.workspace.rootPath, 'composer.json'))); 47 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json.phpunit')), path.join(path.join(vscode.workspace.rootPath, 'sub-directory', 'composer.json'))); 48 | }); 49 | 50 | afterEach(async () => { 51 | // Reset the test/project-stub/.vscode/settings.json settings for each test. 52 | // This allows us to test config options in tests and not harm other tests. 53 | await vscode.workspace.getConfiguration('better-phpunit').update('commandSuffix', null); 54 | await vscode.workspace.getConfiguration('better-phpunit').update('phpunitBinary', null); 55 | await vscode.workspace.getConfiguration('better-phpunit').update('pestBinary', null); 56 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 57 | await vscode.workspace.getConfiguration("better-phpunit").update("xmlConfigFilepath", null); 58 | await vscode.workspace.getConfiguration("better-phpunit").update("suiteSuffix", null); 59 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", false); 60 | }); 61 | 62 | test("Run file outside of method", async () => { 63 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 64 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(0, 0, 0, 0) }); 65 | await vscode.commands.executeCommand('better-phpunit.run'); 66 | 67 | await timeout(waitToAssertInSeconds, () => { 68 | assert.equal(extension.getGlobalCommandInstance().method, undefined); 69 | }); 70 | }); 71 | 72 | test("Run file", async () => { 73 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 74 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 75 | await vscode.commands.executeCommand('better-phpunit.run-file'); 76 | 77 | await timeout(waitToAssertInSeconds, () => { 78 | assert.equal( 79 | extension.getGlobalCommandInstance().output, 80 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest') + ' ' + path.join(vscode.workspace.rootPath, '/tests/SamplePestTest.php') 81 | ); 82 | }); 83 | }); 84 | 85 | test("Run from within first method", async () => { 86 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 87 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(3, 0, 3, 0) }); 88 | await vscode.commands.executeCommand('better-phpunit.run'); 89 | 90 | await timeout(waitToAssertInSeconds, () => { 91 | assert.equal( 92 | extension.getGlobalCommandInstance().method, 93 | "'first'" 94 | ); 95 | }); 96 | }); 97 | 98 | test("Run from within second method", async () => { 99 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 100 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 101 | await vscode.commands.executeCommand('better-phpunit.run'); 102 | 103 | await timeout(waitToAssertInSeconds, () => { 104 | assert.equal( 105 | extension.getGlobalCommandInstance().method, 106 | "'second'" 107 | ); 108 | }); 109 | }); 110 | 111 | test("Detect filename", async () => { 112 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 113 | await vscode.window.showTextDocument(document); 114 | await vscode.commands.executeCommand('better-phpunit.run'); 115 | 116 | await timeout(waitToAssertInSeconds, () => { 117 | assert.equal( 118 | extension.getGlobalCommandInstance().file, 119 | path.join(vscode.workspace.rootPath, '/tests/SamplePestTest.php') 120 | ); 121 | }); 122 | }); 123 | 124 | test("Detect filename with a space", async () => { 125 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'File With Spaces Test.php')); 126 | await vscode.window.showTextDocument(document); 127 | await vscode.commands.executeCommand('better-phpunit.run'); 128 | 129 | await timeout(waitToAssertInSeconds, () => { 130 | assert.equal( 131 | extension.getGlobalCommandInstance().file.replace(/\\/g, 'XX'), 132 | path.join(vscode.workspace.rootPath, '/tests/FileXX WithXX SpacesXX Test.php') 133 | ); 134 | }); 135 | }); 136 | 137 | test("Detect executable", async () => { 138 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 139 | await vscode.window.showTextDocument(document); 140 | await vscode.commands.executeCommand('better-phpunit.run'); 141 | 142 | await timeout(waitToAssertInSeconds, () => { 143 | assert.equal( 144 | extension.getGlobalCommandInstance().binary, 145 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest') 146 | ); 147 | }); 148 | }); 149 | 150 | test("Fallback to default executable if composer.json not detected", async () => { 151 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'composer.json.pest'))); 152 | 153 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 154 | await vscode.window.showTextDocument(document); 155 | await vscode.commands.executeCommand('better-phpunit.run'); 156 | 157 | await timeout(waitToAssertInSeconds, () => { 158 | assert.equal( 159 | extension.getGlobalCommandInstance().binary, 160 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit') 161 | ); 162 | }); 163 | 164 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json.pest')), path.join(path.join(vscode.workspace.rootPath, 'composer.json'))); 165 | }); 166 | 167 | test("Detect executable in sub-directory", async () => { 168 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'composer.json.pest'))); 169 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json.phpunit')), path.join(path.join(vscode.workspace.rootPath, 'composer.json'))); 170 | 171 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'sub-directory', 'tests', 'SampleTest.php')); 172 | await vscode.window.showTextDocument(document); 173 | await vscode.commands.executeCommand('better-phpunit.run'); 174 | 175 | await timeout(waitToAssertInSeconds, () => { 176 | assert.equal( 177 | extension.getGlobalCommandInstance().binary, 178 | path.join(vscode.workspace.rootPath, '/sub-directory/vendor/bin/pest') 179 | ); 180 | }); 181 | 182 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json')), path.join(path.join(vscode.workspace.rootPath, 'composer.json.phpunit'))); 183 | fs.renameSync(path.join(path.join(vscode.workspace.rootPath, 'composer.json.pest')), path.join(path.join(vscode.workspace.rootPath, 'composer.json'))); 184 | }); 185 | 186 | test("Detect configuration in sub-directory", async () => { 187 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'sub-directory', 'tests', 'SampleTest.php')); 188 | await vscode.window.showTextDocument(document); 189 | await vscode.commands.executeCommand('better-phpunit.run'); 190 | 191 | await timeout(waitToAssertInSeconds, () => { 192 | assert.equal( 193 | extension.getGlobalCommandInstance().configuration, 194 | ` --configuration ${path.join(vscode.workspace.rootPath, '/sub-directory/phpunit.xml')}` 195 | ); 196 | }); 197 | }); 198 | 199 | test("Uses configuration found in path supplied in settings", async () => { 200 | await vscode.workspace.getConfiguration('better-phpunit').update('xmlConfigFilepath', '/var/log/phpunit.xml'); 201 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'sub-directory', 'tests', 'SampleTest.php')); 202 | await vscode.window.showTextDocument(document); 203 | await vscode.commands.executeCommand('better-phpunit.run'); 204 | 205 | await timeout(waitToAssertInSeconds, () => { 206 | assert.equal( 207 | extension.getGlobalCommandInstance().configuration, 208 | ` --configuration /var/log/phpunit.xml` 209 | ); 210 | }); 211 | }); 212 | 213 | test("Check full command", async () => { 214 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 215 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 216 | await vscode.commands.executeCommand('better-phpunit.run'); 217 | 218 | await timeout(waitToAssertInSeconds, () => { 219 | assert.equal( 220 | extension.getGlobalCommandInstance().output, 221 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest ') + path.join(vscode.workspace.rootPath, '/tests/SamplePestTest.php') + " --filter 'second'" 222 | ); 223 | }); 224 | }); 225 | 226 | test("Run previous", async () => { 227 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'OtherTest.php')); 228 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(12, 0, 12, 0) }); 229 | await vscode.commands.executeCommand('better-phpunit.run-previous'); 230 | 231 | await timeout(waitToAssertInSeconds, () => { 232 | assert.equal( 233 | extension.getGlobalCommandInstance().output, 234 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest ') + path.join(vscode.workspace.rootPath, '/tests/SamplePestTest.php') + " --filter 'second'" 235 | ); 236 | }); 237 | }); 238 | 239 | test("Run entire suite", async () => { 240 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 241 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 242 | await vscode.commands.executeCommand('better-phpunit.run-suite') 243 | 244 | await timeout(waitToAssertInSeconds, () => { 245 | assert.equal( 246 | extension.getGlobalCommandInstance().output, 247 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest') 248 | ); 249 | }); 250 | }); 251 | 252 | test("Run entire suite with specified options", async () => { 253 | await vscode.workspace.getConfiguration('better-phpunit').update('suiteSuffix', '--testsuite unit --coverage'); 254 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 255 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 256 | await vscode.commands.executeCommand('better-phpunit.run-suite'); 257 | 258 | await timeout(waitToAssertInSeconds, () => { 259 | assert.equal( 260 | extension.getGlobalCommandInstance().output, 261 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest') + ' --testsuite unit --coverage' 262 | ); 263 | }); 264 | }); 265 | 266 | test("Run with commandSuffix config", async () => { 267 | await vscode.workspace.getConfiguration('better-phpunit').update('commandSuffix', '--foo=bar'); 268 | 269 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 270 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 271 | await vscode.commands.executeCommand('better-phpunit.run-suite') 272 | 273 | await timeout(waitToAssertInSeconds, () => { 274 | assert.equal( 275 | extension.getGlobalCommandInstance().output, 276 | path.join(vscode.workspace.rootPath, '/vendor/bin/pest') + ' --foo=bar' 277 | ); 278 | }); 279 | }); 280 | 281 | test("Run with pestBinary config", async () => { 282 | await vscode.workspace.getConfiguration('better-phpunit').update('pestBinary', 'vendor/foo/bar'); 283 | 284 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SamplePestTest.php')); 285 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 286 | await vscode.commands.executeCommand('better-phpunit.run-suite') 287 | 288 | await timeout(waitToAssertInSeconds, () => { 289 | assert.equal( 290 | extension.getGlobalCommandInstance().output, 291 | "vendor/foo/bar" 292 | ); 293 | }); 294 | }); 295 | }); 296 | -------------------------------------------------------------------------------- /src/test/suite/ssh.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import { beforeEach, afterEach } from 'mocha'; 3 | import * as path from 'path'; 4 | 5 | const vscode = require('vscode'); 6 | const extension = require('../../../src/extension'); 7 | 8 | const waitToAssertInSeconds = 5; 9 | 10 | // This is a little helper function to promisify setTimeout, so we can "await" setTimeout. 11 | function timeout(seconds: any, callback: any) { 12 | return new Promise(resolve => { 13 | setTimeout(() => { 14 | callback(); 15 | resolve(''); 16 | }, seconds * waitToAssertInSeconds); 17 | }); 18 | } 19 | 20 | // I'd love for these to be SSH integration tests. 21 | // However, that would take a fair amount of setup. 22 | suite("SSH Tests", function () { 23 | beforeEach(async () => { 24 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", true); 25 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.disableAllOptions", false); 26 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.user", "auser"); 27 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.host", "ahost"); 28 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.port", "2222"); 29 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", false); 30 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.command", null); 31 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.paths", null); 32 | 33 | const paths: any = {}; 34 | paths[path.join(vscode.workspace.rootPath)] = "/some/remote/path"; 35 | paths["/some/other_local/path"] = "/some/other_remote/path"; 36 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.paths", paths); 37 | }); 38 | 39 | afterEach(async () => { 40 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 41 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.disableAllOptions", false); 42 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.user", "auser"); 43 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.host", "ahost"); 44 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.port", "2222"); 45 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.binary", null); 46 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.paths", {}); 47 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", false); 48 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.command", null); 49 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.paths", null); 50 | }); 51 | 52 | test("Commands are not wrapped when SSH is disabled", async function () { 53 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 54 | 55 | console.log(vscode.workspace) 56 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 57 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 58 | await vscode.commands.executeCommand('better-phpunit.run'); 59 | 60 | await timeout(waitToAssertInSeconds, () => { }) 61 | 62 | assert.equal( 63 | extension.getGlobalCommandInstance().output, 64 | path.join(vscode.workspace.rootPath, '/vendor/bin/phpunit ') + path.join(vscode.workspace.rootPath, '/tests/SampleTest.php') + " --filter '^.*::test_first( .*)?$'" 65 | ); 66 | }); 67 | 68 | test("The correct SSH command is run when triggering Better PHPUnit", async function () { 69 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 70 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 71 | await vscode.commands.executeCommand('better-phpunit.run'); 72 | 73 | await timeout(waitToAssertInSeconds, () => { }) 74 | 75 | assert.equal( 76 | extension.getGlobalCommandInstance().output, 77 | 'ssh -tt -p2222 auser@ahost "/some/remote/path/vendor/bin/phpunit /some/remote/path/tests/SampleTest.php --filter \'^.*::test_first( .*)?$\'"' 78 | ); 79 | }); 80 | 81 | test("The correct Docker command is run when triggering Better PHPUnit", async function () { 82 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 83 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", true); 84 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.command", "docker exec CONTAINER"); 85 | const paths: any = {}; 86 | paths[path.join(vscode.workspace.rootPath)] = "/some/remote/path"; 87 | paths["/some/other_local/path"] = "/some/other_remote/path"; 88 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.paths", paths); 89 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 90 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 91 | await vscode.commands.executeCommand('better-phpunit.run'); 92 | 93 | await timeout(waitToAssertInSeconds, () => { }) 94 | 95 | assert.equal( 96 | extension.getGlobalCommandInstance().output, 97 | 'docker exec CONTAINER /some/remote/path/vendor/bin/phpunit /some/remote/path/tests/SampleTest.php --filter \'^.*::test_first( .*)?$\'' 98 | ); 99 | }); 100 | 101 | test("The correct Docker suite command is run when triggering Better PHPUnit", async function () { 102 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.enable", false); 103 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", true); 104 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.command", "docker exec CONTAINER"); 105 | const paths: any = {}; 106 | paths[path.join(vscode.workspace.rootPath)] = "/some/remote/path"; 107 | paths["/some/other_local/path"] = "/some/other_remote/path"; 108 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.paths", paths); 109 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 110 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 111 | await vscode.commands.executeCommand('better-phpunit.run-suite'); 112 | 113 | await timeout(waitToAssertInSeconds, () => { }) 114 | 115 | assert.equal( 116 | extension.getGlobalCommandInstance().output, 117 | 'docker exec CONTAINER /some/remote/path/vendor/bin/phpunit' 118 | ); 119 | }); 120 | 121 | test("The correct Docker command is run via SSH when triggering Better PHPUnit", async function () { 122 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", true); 123 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.command", "docker exec CONTAINER"); 124 | const paths: any = {}; 125 | paths[path.join(vscode.workspace.rootPath)] = "/some/remote/path"; 126 | paths["/some/other_local/path"] = "/some/other_remote/path"; 127 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.paths", paths); 128 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 129 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 130 | await vscode.commands.executeCommand('better-phpunit.run'); 131 | 132 | await timeout(waitToAssertInSeconds, () => { }) 133 | 134 | assert.equal( 135 | extension.getGlobalCommandInstance().output, 136 | 'ssh -tt -p2222 auser@ahost "docker exec CONTAINER /some/remote/path/vendor/bin/phpunit /some/remote/path/tests/SampleTest.php --filter \'^.*::test_first( .*)?$\'"' 137 | ); 138 | }); 139 | 140 | test("The correct Docker suite command is run via SSH when triggering Better PHPUnit", async function () { 141 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.enable", true); 142 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.command", "docker exec CONTAINER"); 143 | const paths: any = {}; 144 | paths[path.join(vscode.workspace.rootPath)] = "/some/remote/path"; 145 | paths["/some/other_local/path"] = "/some/other_remote/path"; 146 | await vscode.workspace.getConfiguration("better-phpunit").update("docker.paths", paths); 147 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 148 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 149 | await vscode.commands.executeCommand('better-phpunit.run-suite'); 150 | 151 | await timeout(waitToAssertInSeconds, () => { }) 152 | 153 | assert.equal( 154 | extension.getGlobalCommandInstance().output, 155 | 'ssh -tt -p2222 auser@ahost "docker exec CONTAINER /some/remote/path/vendor/bin/phpunit"' 156 | ); 157 | }); 158 | 159 | test("Can use a custom ssh binary", async function () { 160 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.binary", "putty -ssh"); 161 | 162 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 163 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 164 | await vscode.commands.executeCommand('better-phpunit.run'); 165 | 166 | await timeout(waitToAssertInSeconds, () => { }) 167 | 168 | assert.equal( 169 | extension.getGlobalCommandInstance().output, 170 | 'putty -ssh -tt -p2222 auser@ahost "/some/remote/path/vendor/bin/phpunit /some/remote/path/tests/SampleTest.php --filter \'^.*::test_first( .*)?$\'"' 171 | ); 172 | }); 173 | 174 | test("Can disable all ssh config options", async function () { 175 | await vscode.workspace.getConfiguration("better-phpunit").update("ssh.disableAllOptions", true); 176 | 177 | let document = await vscode.workspace.openTextDocument(path.join(vscode.workspace.rootPath, 'tests', 'SampleTest.php')); 178 | await vscode.window.showTextDocument(document, { selection: new vscode.Range(7, 0, 7, 0) }); 179 | await vscode.commands.executeCommand('better-phpunit.run'); 180 | 181 | await timeout(waitToAssertInSeconds, () => { }) 182 | 183 | assert.equal( 184 | extension.getGlobalCommandInstance().output, 185 | 'ssh "/some/remote/path/vendor/bin/phpunit /some/remote/path/tests/SampleTest.php --filter \'^.*::test_first( .*)?$\'"' 186 | ); 187 | }); 188 | }); 189 | -------------------------------------------------------------------------------- /test/project-stub/.gitignore: -------------------------------------------------------------------------------- 1 | vendor -------------------------------------------------------------------------------- /test/project-stub/.php_cs.dist: -------------------------------------------------------------------------------- 1 | exclude('storage') 5 | ->exclude('bootstrap') 6 | ->exclude('tests/Feature/__snapshots__') 7 | ->in(__DIR__); 8 | 9 | return PhpCsFixer\Config::create() 10 | ->setRules([ 11 | '@PSR2' => true, 12 | 'method_argument_space' => ['on_multiline' => 'ignore'], 13 | 'ordered_imports' => [ 14 | 'sortAlgorithm' => 'alpha', 15 | ], 16 | 'braces' => [ 17 | 'allow_single_line_closure' => true, 18 | ], 19 | 'trailing_comma_in_multiline_array' => true, 20 | 'single_quote' => false, 21 | 'space_after_semicolon' => true, 22 | 'single_blank_line_before_namespace' => true, 23 | 'no_unused_imports' => true, 24 | 'no_useless_else' => true, 25 | // This is for phpunit functions with no visibility (attr: Adam Wathan) 26 | 'visibility_required' => false, 27 | ]) 28 | ->setFinder($finder); 29 | -------------------------------------------------------------------------------- /test/project-stub/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "better-phpunit.xmlConfigFilepath": null, 3 | "better-phpunit.commandSuffix": null, 4 | "better-phpunit.phpunitBinary": null, 5 | "better-phpunit.pestBinary": null, 6 | "better-phpunit.ssh.enable": false, 7 | "better-phpunit.suiteSuffix": null, 8 | "better-phpunit.docker.enable": false, 9 | "better-phpunit.docker.command": null, 10 | "better-phpunit.docker.paths": null, 11 | "better-phpunit.ssh.binary": null, 12 | "better-phpunit.ssh.disableAllOptions": false, 13 | "better-phpunit.ssh.user": "auser", 14 | "better-phpunit.ssh.host": "ahost", 15 | "better-phpunit.ssh.port": "2222", 16 | "better-phpunit.ssh.paths": {} 17 | } -------------------------------------------------------------------------------- /test/project-stub/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calebporzio/project-stub", 3 | "description": "Test environment for Better PHPUnit VS Code extension", 4 | "authors": [ 5 | { 6 | "name": "Caleb Porzio", 7 | "email": "calebporzio@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "phpunit/phpunit": "^6.4" 12 | }, 13 | "config": { 14 | "allow-plugins": { 15 | "pestphp/pest-plugin": true 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/project-stub/composer.json.pest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calebporzio/project-stub", 3 | "description": "Test environment for Better PHPUnit VS Code extension", 4 | "authors": [ 5 | { 6 | "name": "Caleb Porzio", 7 | "email": "calebporzio@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "pestphp/pest": "^2.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/project-stub/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "2755d823390b07f73e10166e8951c655", 8 | "packages": [ 9 | { 10 | "name": "doctrine/instantiator", 11 | "version": "1.1.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/instantiator.git", 15 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 20 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.1" 25 | }, 26 | "require-dev": { 27 | "athletic/athletic": "~0.1.8", 28 | "ext-pdo": "*", 29 | "ext-phar": "*", 30 | "phpunit/phpunit": "^6.2.3", 31 | "squizlabs/php_codesniffer": "^3.0.2" 32 | }, 33 | "type": "library", 34 | "extra": { 35 | "branch-alias": { 36 | "dev-master": "1.2.x-dev" 37 | } 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 42 | } 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Marco Pivetta", 51 | "email": "ocramius@gmail.com", 52 | "homepage": "http://ocramius.github.com/" 53 | } 54 | ], 55 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 56 | "homepage": "https://github.com/doctrine/instantiator", 57 | "keywords": [ 58 | "constructor", 59 | "instantiate" 60 | ], 61 | "time": "2017-07-22T11:58:36+00:00" 62 | }, 63 | { 64 | "name": "myclabs/deep-copy", 65 | "version": "1.7.0", 66 | "source": { 67 | "type": "git", 68 | "url": "https://github.com/myclabs/DeepCopy.git", 69 | "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" 70 | }, 71 | "dist": { 72 | "type": "zip", 73 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", 74 | "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", 75 | "shasum": "" 76 | }, 77 | "require": { 78 | "php": "^5.6 || ^7.0" 79 | }, 80 | "require-dev": { 81 | "doctrine/collections": "^1.0", 82 | "doctrine/common": "^2.6", 83 | "phpunit/phpunit": "^4.1" 84 | }, 85 | "type": "library", 86 | "autoload": { 87 | "psr-4": { 88 | "DeepCopy\\": "src/DeepCopy/" 89 | }, 90 | "files": [ 91 | "src/DeepCopy/deep_copy.php" 92 | ] 93 | }, 94 | "notification-url": "https://packagist.org/downloads/", 95 | "license": [ 96 | "MIT" 97 | ], 98 | "description": "Create deep copies (clones) of your objects", 99 | "keywords": [ 100 | "clone", 101 | "copy", 102 | "duplicate", 103 | "object", 104 | "object graph" 105 | ], 106 | "time": "2017-10-19T19:58:43+00:00" 107 | }, 108 | { 109 | "name": "phar-io/manifest", 110 | "version": "1.0.1", 111 | "source": { 112 | "type": "git", 113 | "url": "https://github.com/phar-io/manifest.git", 114 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" 115 | }, 116 | "dist": { 117 | "type": "zip", 118 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", 119 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", 120 | "shasum": "" 121 | }, 122 | "require": { 123 | "ext-dom": "*", 124 | "ext-phar": "*", 125 | "phar-io/version": "^1.0.1", 126 | "php": "^5.6 || ^7.0" 127 | }, 128 | "type": "library", 129 | "extra": { 130 | "branch-alias": { 131 | "dev-master": "1.0.x-dev" 132 | } 133 | }, 134 | "autoload": { 135 | "classmap": [ 136 | "src/" 137 | ] 138 | }, 139 | "notification-url": "https://packagist.org/downloads/", 140 | "license": [ 141 | "BSD-3-Clause" 142 | ], 143 | "authors": [ 144 | { 145 | "name": "Arne Blankerts", 146 | "email": "arne@blankerts.de", 147 | "role": "Developer" 148 | }, 149 | { 150 | "name": "Sebastian Heuer", 151 | "email": "sebastian@phpeople.de", 152 | "role": "Developer" 153 | }, 154 | { 155 | "name": "Sebastian Bergmann", 156 | "email": "sebastian@phpunit.de", 157 | "role": "Developer" 158 | } 159 | ], 160 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 161 | "time": "2017-03-05T18:14:27+00:00" 162 | }, 163 | { 164 | "name": "phar-io/version", 165 | "version": "1.0.1", 166 | "source": { 167 | "type": "git", 168 | "url": "https://github.com/phar-io/version.git", 169 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" 170 | }, 171 | "dist": { 172 | "type": "zip", 173 | "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", 174 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", 175 | "shasum": "" 176 | }, 177 | "require": { 178 | "php": "^5.6 || ^7.0" 179 | }, 180 | "type": "library", 181 | "autoload": { 182 | "classmap": [ 183 | "src/" 184 | ] 185 | }, 186 | "notification-url": "https://packagist.org/downloads/", 187 | "license": [ 188 | "BSD-3-Clause" 189 | ], 190 | "authors": [ 191 | { 192 | "name": "Arne Blankerts", 193 | "email": "arne@blankerts.de", 194 | "role": "Developer" 195 | }, 196 | { 197 | "name": "Sebastian Heuer", 198 | "email": "sebastian@phpeople.de", 199 | "role": "Developer" 200 | }, 201 | { 202 | "name": "Sebastian Bergmann", 203 | "email": "sebastian@phpunit.de", 204 | "role": "Developer" 205 | } 206 | ], 207 | "description": "Library for handling version information and constraints", 208 | "time": "2017-03-05T17:38:23+00:00" 209 | }, 210 | { 211 | "name": "phpdocumentor/reflection-common", 212 | "version": "1.0.1", 213 | "source": { 214 | "type": "git", 215 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 216 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 217 | }, 218 | "dist": { 219 | "type": "zip", 220 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 221 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 222 | "shasum": "" 223 | }, 224 | "require": { 225 | "php": ">=5.5" 226 | }, 227 | "require-dev": { 228 | "phpunit/phpunit": "^4.6" 229 | }, 230 | "type": "library", 231 | "extra": { 232 | "branch-alias": { 233 | "dev-master": "1.0.x-dev" 234 | } 235 | }, 236 | "autoload": { 237 | "psr-4": { 238 | "phpDocumentor\\Reflection\\": [ 239 | "src" 240 | ] 241 | } 242 | }, 243 | "notification-url": "https://packagist.org/downloads/", 244 | "license": [ 245 | "MIT" 246 | ], 247 | "authors": [ 248 | { 249 | "name": "Jaap van Otterdijk", 250 | "email": "opensource@ijaap.nl" 251 | } 252 | ], 253 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 254 | "homepage": "http://www.phpdoc.org", 255 | "keywords": [ 256 | "FQSEN", 257 | "phpDocumentor", 258 | "phpdoc", 259 | "reflection", 260 | "static analysis" 261 | ], 262 | "time": "2017-09-11T18:02:19+00:00" 263 | }, 264 | { 265 | "name": "phpdocumentor/reflection-docblock", 266 | "version": "4.1.1", 267 | "source": { 268 | "type": "git", 269 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 270 | "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2" 271 | }, 272 | "dist": { 273 | "type": "zip", 274 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2", 275 | "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2", 276 | "shasum": "" 277 | }, 278 | "require": { 279 | "php": "^7.0", 280 | "phpdocumentor/reflection-common": "^1.0@dev", 281 | "phpdocumentor/type-resolver": "^0.4.0", 282 | "webmozart/assert": "^1.0" 283 | }, 284 | "require-dev": { 285 | "mockery/mockery": "^0.9.4", 286 | "phpunit/phpunit": "^4.4" 287 | }, 288 | "type": "library", 289 | "autoload": { 290 | "psr-4": { 291 | "phpDocumentor\\Reflection\\": [ 292 | "src/" 293 | ] 294 | } 295 | }, 296 | "notification-url": "https://packagist.org/downloads/", 297 | "license": [ 298 | "MIT" 299 | ], 300 | "authors": [ 301 | { 302 | "name": "Mike van Riel", 303 | "email": "me@mikevanriel.com" 304 | } 305 | ], 306 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 307 | "time": "2017-08-30T18:51:59+00:00" 308 | }, 309 | { 310 | "name": "phpdocumentor/type-resolver", 311 | "version": "0.4.0", 312 | "source": { 313 | "type": "git", 314 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 315 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 316 | }, 317 | "dist": { 318 | "type": "zip", 319 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 320 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 321 | "shasum": "" 322 | }, 323 | "require": { 324 | "php": "^5.5 || ^7.0", 325 | "phpdocumentor/reflection-common": "^1.0" 326 | }, 327 | "require-dev": { 328 | "mockery/mockery": "^0.9.4", 329 | "phpunit/phpunit": "^5.2||^4.8.24" 330 | }, 331 | "type": "library", 332 | "extra": { 333 | "branch-alias": { 334 | "dev-master": "1.0.x-dev" 335 | } 336 | }, 337 | "autoload": { 338 | "psr-4": { 339 | "phpDocumentor\\Reflection\\": [ 340 | "src/" 341 | ] 342 | } 343 | }, 344 | "notification-url": "https://packagist.org/downloads/", 345 | "license": [ 346 | "MIT" 347 | ], 348 | "authors": [ 349 | { 350 | "name": "Mike van Riel", 351 | "email": "me@mikevanriel.com" 352 | } 353 | ], 354 | "time": "2017-07-14T14:27:02+00:00" 355 | }, 356 | { 357 | "name": "phpspec/prophecy", 358 | "version": "v1.7.2", 359 | "source": { 360 | "type": "git", 361 | "url": "https://github.com/phpspec/prophecy.git", 362 | "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" 363 | }, 364 | "dist": { 365 | "type": "zip", 366 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", 367 | "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", 368 | "shasum": "" 369 | }, 370 | "require": { 371 | "doctrine/instantiator": "^1.0.2", 372 | "php": "^5.3|^7.0", 373 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 374 | "sebastian/comparator": "^1.1|^2.0", 375 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 376 | }, 377 | "require-dev": { 378 | "phpspec/phpspec": "^2.5|^3.2", 379 | "phpunit/phpunit": "^4.8 || ^5.6.5" 380 | }, 381 | "type": "library", 382 | "extra": { 383 | "branch-alias": { 384 | "dev-master": "1.7.x-dev" 385 | } 386 | }, 387 | "autoload": { 388 | "psr-0": { 389 | "Prophecy\\": "src/" 390 | } 391 | }, 392 | "notification-url": "https://packagist.org/downloads/", 393 | "license": [ 394 | "MIT" 395 | ], 396 | "authors": [ 397 | { 398 | "name": "Konstantin Kudryashov", 399 | "email": "ever.zet@gmail.com", 400 | "homepage": "http://everzet.com" 401 | }, 402 | { 403 | "name": "Marcello Duarte", 404 | "email": "marcello.duarte@gmail.com" 405 | } 406 | ], 407 | "description": "Highly opinionated mocking framework for PHP 5.3+", 408 | "homepage": "https://github.com/phpspec/prophecy", 409 | "keywords": [ 410 | "Double", 411 | "Dummy", 412 | "fake", 413 | "mock", 414 | "spy", 415 | "stub" 416 | ], 417 | "time": "2017-09-04T11:05:03+00:00" 418 | }, 419 | { 420 | "name": "phpunit/php-code-coverage", 421 | "version": "5.2.3", 422 | "source": { 423 | "type": "git", 424 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 425 | "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d" 426 | }, 427 | "dist": { 428 | "type": "zip", 429 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", 430 | "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", 431 | "shasum": "" 432 | }, 433 | "require": { 434 | "ext-dom": "*", 435 | "ext-xmlwriter": "*", 436 | "php": "^7.0", 437 | "phpunit/php-file-iterator": "^1.4.2", 438 | "phpunit/php-text-template": "^1.2.1", 439 | "phpunit/php-token-stream": "^2.0", 440 | "sebastian/code-unit-reverse-lookup": "^1.0.1", 441 | "sebastian/environment": "^3.0", 442 | "sebastian/version": "^2.0.1", 443 | "theseer/tokenizer": "^1.1" 444 | }, 445 | "require-dev": { 446 | "ext-xdebug": "^2.5", 447 | "phpunit/phpunit": "^6.0" 448 | }, 449 | "suggest": { 450 | "ext-xdebug": "^2.5.5" 451 | }, 452 | "type": "library", 453 | "extra": { 454 | "branch-alias": { 455 | "dev-master": "5.2.x-dev" 456 | } 457 | }, 458 | "autoload": { 459 | "classmap": [ 460 | "src/" 461 | ] 462 | }, 463 | "notification-url": "https://packagist.org/downloads/", 464 | "license": [ 465 | "BSD-3-Clause" 466 | ], 467 | "authors": [ 468 | { 469 | "name": "Sebastian Bergmann", 470 | "email": "sb@sebastian-bergmann.de", 471 | "role": "lead" 472 | } 473 | ], 474 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 475 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 476 | "keywords": [ 477 | "coverage", 478 | "testing", 479 | "xunit" 480 | ], 481 | "time": "2017-11-03T13:47:33+00:00" 482 | }, 483 | { 484 | "name": "phpunit/php-file-iterator", 485 | "version": "1.4.2", 486 | "source": { 487 | "type": "git", 488 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 489 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" 490 | }, 491 | "dist": { 492 | "type": "zip", 493 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 494 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 495 | "shasum": "" 496 | }, 497 | "require": { 498 | "php": ">=5.3.3" 499 | }, 500 | "type": "library", 501 | "extra": { 502 | "branch-alias": { 503 | "dev-master": "1.4.x-dev" 504 | } 505 | }, 506 | "autoload": { 507 | "classmap": [ 508 | "src/" 509 | ] 510 | }, 511 | "notification-url": "https://packagist.org/downloads/", 512 | "license": [ 513 | "BSD-3-Clause" 514 | ], 515 | "authors": [ 516 | { 517 | "name": "Sebastian Bergmann", 518 | "email": "sb@sebastian-bergmann.de", 519 | "role": "lead" 520 | } 521 | ], 522 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 523 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 524 | "keywords": [ 525 | "filesystem", 526 | "iterator" 527 | ], 528 | "time": "2016-10-03T07:40:28+00:00" 529 | }, 530 | { 531 | "name": "phpunit/php-text-template", 532 | "version": "1.2.1", 533 | "source": { 534 | "type": "git", 535 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 536 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 537 | }, 538 | "dist": { 539 | "type": "zip", 540 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 541 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 542 | "shasum": "" 543 | }, 544 | "require": { 545 | "php": ">=5.3.3" 546 | }, 547 | "type": "library", 548 | "autoload": { 549 | "classmap": [ 550 | "src/" 551 | ] 552 | }, 553 | "notification-url": "https://packagist.org/downloads/", 554 | "license": [ 555 | "BSD-3-Clause" 556 | ], 557 | "authors": [ 558 | { 559 | "name": "Sebastian Bergmann", 560 | "email": "sebastian@phpunit.de", 561 | "role": "lead" 562 | } 563 | ], 564 | "description": "Simple template engine.", 565 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 566 | "keywords": [ 567 | "template" 568 | ], 569 | "time": "2015-06-21T13:50:34+00:00" 570 | }, 571 | { 572 | "name": "phpunit/php-timer", 573 | "version": "1.0.9", 574 | "source": { 575 | "type": "git", 576 | "url": "https://github.com/sebastianbergmann/php-timer.git", 577 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 578 | }, 579 | "dist": { 580 | "type": "zip", 581 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 582 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 583 | "shasum": "" 584 | }, 585 | "require": { 586 | "php": "^5.3.3 || ^7.0" 587 | }, 588 | "require-dev": { 589 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 590 | }, 591 | "type": "library", 592 | "extra": { 593 | "branch-alias": { 594 | "dev-master": "1.0-dev" 595 | } 596 | }, 597 | "autoload": { 598 | "classmap": [ 599 | "src/" 600 | ] 601 | }, 602 | "notification-url": "https://packagist.org/downloads/", 603 | "license": [ 604 | "BSD-3-Clause" 605 | ], 606 | "authors": [ 607 | { 608 | "name": "Sebastian Bergmann", 609 | "email": "sb@sebastian-bergmann.de", 610 | "role": "lead" 611 | } 612 | ], 613 | "description": "Utility class for timing", 614 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 615 | "keywords": [ 616 | "timer" 617 | ], 618 | "time": "2017-02-26T11:10:40+00:00" 619 | }, 620 | { 621 | "name": "phpunit/php-token-stream", 622 | "version": "2.0.1", 623 | "source": { 624 | "type": "git", 625 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 626 | "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0" 627 | }, 628 | "dist": { 629 | "type": "zip", 630 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0", 631 | "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0", 632 | "shasum": "" 633 | }, 634 | "require": { 635 | "ext-tokenizer": "*", 636 | "php": "^7.0" 637 | }, 638 | "require-dev": { 639 | "phpunit/phpunit": "^6.2.4" 640 | }, 641 | "type": "library", 642 | "extra": { 643 | "branch-alias": { 644 | "dev-master": "2.0-dev" 645 | } 646 | }, 647 | "autoload": { 648 | "classmap": [ 649 | "src/" 650 | ] 651 | }, 652 | "notification-url": "https://packagist.org/downloads/", 653 | "license": [ 654 | "BSD-3-Clause" 655 | ], 656 | "authors": [ 657 | { 658 | "name": "Sebastian Bergmann", 659 | "email": "sebastian@phpunit.de" 660 | } 661 | ], 662 | "description": "Wrapper around PHP's tokenizer extension.", 663 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 664 | "keywords": [ 665 | "tokenizer" 666 | ], 667 | "time": "2017-08-20T05:47:52+00:00" 668 | }, 669 | { 670 | "name": "phpunit/phpunit", 671 | "version": "6.4.4", 672 | "source": { 673 | "type": "git", 674 | "url": "https://github.com/sebastianbergmann/phpunit.git", 675 | "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932" 676 | }, 677 | "dist": { 678 | "type": "zip", 679 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/562f7dc75d46510a4ed5d16189ae57fbe45a9932", 680 | "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932", 681 | "shasum": "" 682 | }, 683 | "require": { 684 | "ext-dom": "*", 685 | "ext-json": "*", 686 | "ext-libxml": "*", 687 | "ext-mbstring": "*", 688 | "ext-xml": "*", 689 | "myclabs/deep-copy": "^1.6.1", 690 | "phar-io/manifest": "^1.0.1", 691 | "phar-io/version": "^1.0", 692 | "php": "^7.0", 693 | "phpspec/prophecy": "^1.7", 694 | "phpunit/php-code-coverage": "^5.2.2", 695 | "phpunit/php-file-iterator": "^1.4.2", 696 | "phpunit/php-text-template": "^1.2.1", 697 | "phpunit/php-timer": "^1.0.9", 698 | "phpunit/phpunit-mock-objects": "^4.0.3", 699 | "sebastian/comparator": "^2.0.2", 700 | "sebastian/diff": "^2.0", 701 | "sebastian/environment": "^3.1", 702 | "sebastian/exporter": "^3.1", 703 | "sebastian/global-state": "^2.0", 704 | "sebastian/object-enumerator": "^3.0.3", 705 | "sebastian/resource-operations": "^1.0", 706 | "sebastian/version": "^2.0.1" 707 | }, 708 | "conflict": { 709 | "phpdocumentor/reflection-docblock": "3.0.2", 710 | "phpunit/dbunit": "<3.0" 711 | }, 712 | "require-dev": { 713 | "ext-pdo": "*" 714 | }, 715 | "suggest": { 716 | "ext-xdebug": "*", 717 | "phpunit/php-invoker": "^1.1" 718 | }, 719 | "bin": [ 720 | "phpunit" 721 | ], 722 | "type": "library", 723 | "extra": { 724 | "branch-alias": { 725 | "dev-master": "6.4.x-dev" 726 | } 727 | }, 728 | "autoload": { 729 | "classmap": [ 730 | "src/" 731 | ] 732 | }, 733 | "notification-url": "https://packagist.org/downloads/", 734 | "license": [ 735 | "BSD-3-Clause" 736 | ], 737 | "authors": [ 738 | { 739 | "name": "Sebastian Bergmann", 740 | "email": "sebastian@phpunit.de", 741 | "role": "lead" 742 | } 743 | ], 744 | "description": "The PHP Unit Testing framework.", 745 | "homepage": "https://phpunit.de/", 746 | "keywords": [ 747 | "phpunit", 748 | "testing", 749 | "xunit" 750 | ], 751 | "time": "2017-11-08T11:26:09+00:00" 752 | }, 753 | { 754 | "name": "phpunit/phpunit-mock-objects", 755 | "version": "4.0.4", 756 | "source": { 757 | "type": "git", 758 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 759 | "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" 760 | }, 761 | "dist": { 762 | "type": "zip", 763 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", 764 | "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", 765 | "shasum": "" 766 | }, 767 | "require": { 768 | "doctrine/instantiator": "^1.0.5", 769 | "php": "^7.0", 770 | "phpunit/php-text-template": "^1.2.1", 771 | "sebastian/exporter": "^3.0" 772 | }, 773 | "conflict": { 774 | "phpunit/phpunit": "<6.0" 775 | }, 776 | "require-dev": { 777 | "phpunit/phpunit": "^6.0" 778 | }, 779 | "suggest": { 780 | "ext-soap": "*" 781 | }, 782 | "type": "library", 783 | "extra": { 784 | "branch-alias": { 785 | "dev-master": "4.0.x-dev" 786 | } 787 | }, 788 | "autoload": { 789 | "classmap": [ 790 | "src/" 791 | ] 792 | }, 793 | "notification-url": "https://packagist.org/downloads/", 794 | "license": [ 795 | "BSD-3-Clause" 796 | ], 797 | "authors": [ 798 | { 799 | "name": "Sebastian Bergmann", 800 | "email": "sb@sebastian-bergmann.de", 801 | "role": "lead" 802 | } 803 | ], 804 | "description": "Mock Object library for PHPUnit", 805 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 806 | "keywords": [ 807 | "mock", 808 | "xunit" 809 | ], 810 | "time": "2017-08-03T14:08:16+00:00" 811 | }, 812 | { 813 | "name": "sebastian/code-unit-reverse-lookup", 814 | "version": "1.0.1", 815 | "source": { 816 | "type": "git", 817 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 818 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 819 | }, 820 | "dist": { 821 | "type": "zip", 822 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 823 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 824 | "shasum": "" 825 | }, 826 | "require": { 827 | "php": "^5.6 || ^7.0" 828 | }, 829 | "require-dev": { 830 | "phpunit/phpunit": "^5.7 || ^6.0" 831 | }, 832 | "type": "library", 833 | "extra": { 834 | "branch-alias": { 835 | "dev-master": "1.0.x-dev" 836 | } 837 | }, 838 | "autoload": { 839 | "classmap": [ 840 | "src/" 841 | ] 842 | }, 843 | "notification-url": "https://packagist.org/downloads/", 844 | "license": [ 845 | "BSD-3-Clause" 846 | ], 847 | "authors": [ 848 | { 849 | "name": "Sebastian Bergmann", 850 | "email": "sebastian@phpunit.de" 851 | } 852 | ], 853 | "description": "Looks up which function or method a line of code belongs to", 854 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 855 | "time": "2017-03-04T06:30:41+00:00" 856 | }, 857 | { 858 | "name": "sebastian/comparator", 859 | "version": "2.1.0", 860 | "source": { 861 | "type": "git", 862 | "url": "https://github.com/sebastianbergmann/comparator.git", 863 | "reference": "1174d9018191e93cb9d719edec01257fc05f8158" 864 | }, 865 | "dist": { 866 | "type": "zip", 867 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1174d9018191e93cb9d719edec01257fc05f8158", 868 | "reference": "1174d9018191e93cb9d719edec01257fc05f8158", 869 | "shasum": "" 870 | }, 871 | "require": { 872 | "php": "^7.0", 873 | "sebastian/diff": "^2.0", 874 | "sebastian/exporter": "^3.1" 875 | }, 876 | "require-dev": { 877 | "phpunit/phpunit": "^6.4" 878 | }, 879 | "type": "library", 880 | "extra": { 881 | "branch-alias": { 882 | "dev-master": "2.1.x-dev" 883 | } 884 | }, 885 | "autoload": { 886 | "classmap": [ 887 | "src/" 888 | ] 889 | }, 890 | "notification-url": "https://packagist.org/downloads/", 891 | "license": [ 892 | "BSD-3-Clause" 893 | ], 894 | "authors": [ 895 | { 896 | "name": "Jeff Welch", 897 | "email": "whatthejeff@gmail.com" 898 | }, 899 | { 900 | "name": "Volker Dusch", 901 | "email": "github@wallbash.com" 902 | }, 903 | { 904 | "name": "Bernhard Schussek", 905 | "email": "bschussek@2bepublished.at" 906 | }, 907 | { 908 | "name": "Sebastian Bergmann", 909 | "email": "sebastian@phpunit.de" 910 | } 911 | ], 912 | "description": "Provides the functionality to compare PHP values for equality", 913 | "homepage": "https://github.com/sebastianbergmann/comparator", 914 | "keywords": [ 915 | "comparator", 916 | "compare", 917 | "equality" 918 | ], 919 | "time": "2017-11-03T07:16:52+00:00" 920 | }, 921 | { 922 | "name": "sebastian/diff", 923 | "version": "2.0.1", 924 | "source": { 925 | "type": "git", 926 | "url": "https://github.com/sebastianbergmann/diff.git", 927 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" 928 | }, 929 | "dist": { 930 | "type": "zip", 931 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 932 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 933 | "shasum": "" 934 | }, 935 | "require": { 936 | "php": "^7.0" 937 | }, 938 | "require-dev": { 939 | "phpunit/phpunit": "^6.2" 940 | }, 941 | "type": "library", 942 | "extra": { 943 | "branch-alias": { 944 | "dev-master": "2.0-dev" 945 | } 946 | }, 947 | "autoload": { 948 | "classmap": [ 949 | "src/" 950 | ] 951 | }, 952 | "notification-url": "https://packagist.org/downloads/", 953 | "license": [ 954 | "BSD-3-Clause" 955 | ], 956 | "authors": [ 957 | { 958 | "name": "Kore Nordmann", 959 | "email": "mail@kore-nordmann.de" 960 | }, 961 | { 962 | "name": "Sebastian Bergmann", 963 | "email": "sebastian@phpunit.de" 964 | } 965 | ], 966 | "description": "Diff implementation", 967 | "homepage": "https://github.com/sebastianbergmann/diff", 968 | "keywords": [ 969 | "diff" 970 | ], 971 | "time": "2017-08-03T08:09:46+00:00" 972 | }, 973 | { 974 | "name": "sebastian/environment", 975 | "version": "3.1.0", 976 | "source": { 977 | "type": "git", 978 | "url": "https://github.com/sebastianbergmann/environment.git", 979 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" 980 | }, 981 | "dist": { 982 | "type": "zip", 983 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 984 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 985 | "shasum": "" 986 | }, 987 | "require": { 988 | "php": "^7.0" 989 | }, 990 | "require-dev": { 991 | "phpunit/phpunit": "^6.1" 992 | }, 993 | "type": "library", 994 | "extra": { 995 | "branch-alias": { 996 | "dev-master": "3.1.x-dev" 997 | } 998 | }, 999 | "autoload": { 1000 | "classmap": [ 1001 | "src/" 1002 | ] 1003 | }, 1004 | "notification-url": "https://packagist.org/downloads/", 1005 | "license": [ 1006 | "BSD-3-Clause" 1007 | ], 1008 | "authors": [ 1009 | { 1010 | "name": "Sebastian Bergmann", 1011 | "email": "sebastian@phpunit.de" 1012 | } 1013 | ], 1014 | "description": "Provides functionality to handle HHVM/PHP environments", 1015 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1016 | "keywords": [ 1017 | "Xdebug", 1018 | "environment", 1019 | "hhvm" 1020 | ], 1021 | "time": "2017-07-01T08:51:00+00:00" 1022 | }, 1023 | { 1024 | "name": "sebastian/exporter", 1025 | "version": "3.1.0", 1026 | "source": { 1027 | "type": "git", 1028 | "url": "https://github.com/sebastianbergmann/exporter.git", 1029 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" 1030 | }, 1031 | "dist": { 1032 | "type": "zip", 1033 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", 1034 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", 1035 | "shasum": "" 1036 | }, 1037 | "require": { 1038 | "php": "^7.0", 1039 | "sebastian/recursion-context": "^3.0" 1040 | }, 1041 | "require-dev": { 1042 | "ext-mbstring": "*", 1043 | "phpunit/phpunit": "^6.0" 1044 | }, 1045 | "type": "library", 1046 | "extra": { 1047 | "branch-alias": { 1048 | "dev-master": "3.1.x-dev" 1049 | } 1050 | }, 1051 | "autoload": { 1052 | "classmap": [ 1053 | "src/" 1054 | ] 1055 | }, 1056 | "notification-url": "https://packagist.org/downloads/", 1057 | "license": [ 1058 | "BSD-3-Clause" 1059 | ], 1060 | "authors": [ 1061 | { 1062 | "name": "Jeff Welch", 1063 | "email": "whatthejeff@gmail.com" 1064 | }, 1065 | { 1066 | "name": "Volker Dusch", 1067 | "email": "github@wallbash.com" 1068 | }, 1069 | { 1070 | "name": "Bernhard Schussek", 1071 | "email": "bschussek@2bepublished.at" 1072 | }, 1073 | { 1074 | "name": "Sebastian Bergmann", 1075 | "email": "sebastian@phpunit.de" 1076 | }, 1077 | { 1078 | "name": "Adam Harvey", 1079 | "email": "aharvey@php.net" 1080 | } 1081 | ], 1082 | "description": "Provides the functionality to export PHP variables for visualization", 1083 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1084 | "keywords": [ 1085 | "export", 1086 | "exporter" 1087 | ], 1088 | "time": "2017-04-03T13:19:02+00:00" 1089 | }, 1090 | { 1091 | "name": "sebastian/global-state", 1092 | "version": "2.0.0", 1093 | "source": { 1094 | "type": "git", 1095 | "url": "https://github.com/sebastianbergmann/global-state.git", 1096 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" 1097 | }, 1098 | "dist": { 1099 | "type": "zip", 1100 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1101 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1102 | "shasum": "" 1103 | }, 1104 | "require": { 1105 | "php": "^7.0" 1106 | }, 1107 | "require-dev": { 1108 | "phpunit/phpunit": "^6.0" 1109 | }, 1110 | "suggest": { 1111 | "ext-uopz": "*" 1112 | }, 1113 | "type": "library", 1114 | "extra": { 1115 | "branch-alias": { 1116 | "dev-master": "2.0-dev" 1117 | } 1118 | }, 1119 | "autoload": { 1120 | "classmap": [ 1121 | "src/" 1122 | ] 1123 | }, 1124 | "notification-url": "https://packagist.org/downloads/", 1125 | "license": [ 1126 | "BSD-3-Clause" 1127 | ], 1128 | "authors": [ 1129 | { 1130 | "name": "Sebastian Bergmann", 1131 | "email": "sebastian@phpunit.de" 1132 | } 1133 | ], 1134 | "description": "Snapshotting of global state", 1135 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1136 | "keywords": [ 1137 | "global state" 1138 | ], 1139 | "time": "2017-04-27T15:39:26+00:00" 1140 | }, 1141 | { 1142 | "name": "sebastian/object-enumerator", 1143 | "version": "3.0.3", 1144 | "source": { 1145 | "type": "git", 1146 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1147 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" 1148 | }, 1149 | "dist": { 1150 | "type": "zip", 1151 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1152 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1153 | "shasum": "" 1154 | }, 1155 | "require": { 1156 | "php": "^7.0", 1157 | "sebastian/object-reflector": "^1.1.1", 1158 | "sebastian/recursion-context": "^3.0" 1159 | }, 1160 | "require-dev": { 1161 | "phpunit/phpunit": "^6.0" 1162 | }, 1163 | "type": "library", 1164 | "extra": { 1165 | "branch-alias": { 1166 | "dev-master": "3.0.x-dev" 1167 | } 1168 | }, 1169 | "autoload": { 1170 | "classmap": [ 1171 | "src/" 1172 | ] 1173 | }, 1174 | "notification-url": "https://packagist.org/downloads/", 1175 | "license": [ 1176 | "BSD-3-Clause" 1177 | ], 1178 | "authors": [ 1179 | { 1180 | "name": "Sebastian Bergmann", 1181 | "email": "sebastian@phpunit.de" 1182 | } 1183 | ], 1184 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1185 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1186 | "time": "2017-08-03T12:35:26+00:00" 1187 | }, 1188 | { 1189 | "name": "sebastian/object-reflector", 1190 | "version": "1.1.1", 1191 | "source": { 1192 | "type": "git", 1193 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1194 | "reference": "773f97c67f28de00d397be301821b06708fca0be" 1195 | }, 1196 | "dist": { 1197 | "type": "zip", 1198 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", 1199 | "reference": "773f97c67f28de00d397be301821b06708fca0be", 1200 | "shasum": "" 1201 | }, 1202 | "require": { 1203 | "php": "^7.0" 1204 | }, 1205 | "require-dev": { 1206 | "phpunit/phpunit": "^6.0" 1207 | }, 1208 | "type": "library", 1209 | "extra": { 1210 | "branch-alias": { 1211 | "dev-master": "1.1-dev" 1212 | } 1213 | }, 1214 | "autoload": { 1215 | "classmap": [ 1216 | "src/" 1217 | ] 1218 | }, 1219 | "notification-url": "https://packagist.org/downloads/", 1220 | "license": [ 1221 | "BSD-3-Clause" 1222 | ], 1223 | "authors": [ 1224 | { 1225 | "name": "Sebastian Bergmann", 1226 | "email": "sebastian@phpunit.de" 1227 | } 1228 | ], 1229 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1230 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1231 | "time": "2017-03-29T09:07:27+00:00" 1232 | }, 1233 | { 1234 | "name": "sebastian/recursion-context", 1235 | "version": "3.0.0", 1236 | "source": { 1237 | "type": "git", 1238 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1239 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" 1240 | }, 1241 | "dist": { 1242 | "type": "zip", 1243 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1244 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1245 | "shasum": "" 1246 | }, 1247 | "require": { 1248 | "php": "^7.0" 1249 | }, 1250 | "require-dev": { 1251 | "phpunit/phpunit": "^6.0" 1252 | }, 1253 | "type": "library", 1254 | "extra": { 1255 | "branch-alias": { 1256 | "dev-master": "3.0.x-dev" 1257 | } 1258 | }, 1259 | "autoload": { 1260 | "classmap": [ 1261 | "src/" 1262 | ] 1263 | }, 1264 | "notification-url": "https://packagist.org/downloads/", 1265 | "license": [ 1266 | "BSD-3-Clause" 1267 | ], 1268 | "authors": [ 1269 | { 1270 | "name": "Jeff Welch", 1271 | "email": "whatthejeff@gmail.com" 1272 | }, 1273 | { 1274 | "name": "Sebastian Bergmann", 1275 | "email": "sebastian@phpunit.de" 1276 | }, 1277 | { 1278 | "name": "Adam Harvey", 1279 | "email": "aharvey@php.net" 1280 | } 1281 | ], 1282 | "description": "Provides functionality to recursively process PHP variables", 1283 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1284 | "time": "2017-03-03T06:23:57+00:00" 1285 | }, 1286 | { 1287 | "name": "sebastian/resource-operations", 1288 | "version": "1.0.0", 1289 | "source": { 1290 | "type": "git", 1291 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1292 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1293 | }, 1294 | "dist": { 1295 | "type": "zip", 1296 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1297 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1298 | "shasum": "" 1299 | }, 1300 | "require": { 1301 | "php": ">=5.6.0" 1302 | }, 1303 | "type": "library", 1304 | "extra": { 1305 | "branch-alias": { 1306 | "dev-master": "1.0.x-dev" 1307 | } 1308 | }, 1309 | "autoload": { 1310 | "classmap": [ 1311 | "src/" 1312 | ] 1313 | }, 1314 | "notification-url": "https://packagist.org/downloads/", 1315 | "license": [ 1316 | "BSD-3-Clause" 1317 | ], 1318 | "authors": [ 1319 | { 1320 | "name": "Sebastian Bergmann", 1321 | "email": "sebastian@phpunit.de" 1322 | } 1323 | ], 1324 | "description": "Provides a list of PHP built-in functions that operate on resources", 1325 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1326 | "time": "2015-07-28T20:34:47+00:00" 1327 | }, 1328 | { 1329 | "name": "sebastian/version", 1330 | "version": "2.0.1", 1331 | "source": { 1332 | "type": "git", 1333 | "url": "https://github.com/sebastianbergmann/version.git", 1334 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1335 | }, 1336 | "dist": { 1337 | "type": "zip", 1338 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1339 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1340 | "shasum": "" 1341 | }, 1342 | "require": { 1343 | "php": ">=5.6" 1344 | }, 1345 | "type": "library", 1346 | "extra": { 1347 | "branch-alias": { 1348 | "dev-master": "2.0.x-dev" 1349 | } 1350 | }, 1351 | "autoload": { 1352 | "classmap": [ 1353 | "src/" 1354 | ] 1355 | }, 1356 | "notification-url": "https://packagist.org/downloads/", 1357 | "license": [ 1358 | "BSD-3-Clause" 1359 | ], 1360 | "authors": [ 1361 | { 1362 | "name": "Sebastian Bergmann", 1363 | "email": "sebastian@phpunit.de", 1364 | "role": "lead" 1365 | } 1366 | ], 1367 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1368 | "homepage": "https://github.com/sebastianbergmann/version", 1369 | "time": "2016-10-03T07:35:21+00:00" 1370 | }, 1371 | { 1372 | "name": "theseer/tokenizer", 1373 | "version": "1.1.0", 1374 | "source": { 1375 | "type": "git", 1376 | "url": "https://github.com/theseer/tokenizer.git", 1377 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" 1378 | }, 1379 | "dist": { 1380 | "type": "zip", 1381 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", 1382 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", 1383 | "shasum": "" 1384 | }, 1385 | "require": { 1386 | "ext-dom": "*", 1387 | "ext-tokenizer": "*", 1388 | "ext-xmlwriter": "*", 1389 | "php": "^7.0" 1390 | }, 1391 | "type": "library", 1392 | "autoload": { 1393 | "classmap": [ 1394 | "src/" 1395 | ] 1396 | }, 1397 | "notification-url": "https://packagist.org/downloads/", 1398 | "license": [ 1399 | "BSD-3-Clause" 1400 | ], 1401 | "authors": [ 1402 | { 1403 | "name": "Arne Blankerts", 1404 | "email": "arne@blankerts.de", 1405 | "role": "Developer" 1406 | } 1407 | ], 1408 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 1409 | "time": "2017-04-07T12:08:54+00:00" 1410 | }, 1411 | { 1412 | "name": "webmozart/assert", 1413 | "version": "1.2.0", 1414 | "source": { 1415 | "type": "git", 1416 | "url": "https://github.com/webmozart/assert.git", 1417 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" 1418 | }, 1419 | "dist": { 1420 | "type": "zip", 1421 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", 1422 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", 1423 | "shasum": "" 1424 | }, 1425 | "require": { 1426 | "php": "^5.3.3 || ^7.0" 1427 | }, 1428 | "require-dev": { 1429 | "phpunit/phpunit": "^4.6", 1430 | "sebastian/version": "^1.0.1" 1431 | }, 1432 | "type": "library", 1433 | "extra": { 1434 | "branch-alias": { 1435 | "dev-master": "1.3-dev" 1436 | } 1437 | }, 1438 | "autoload": { 1439 | "psr-4": { 1440 | "Webmozart\\Assert\\": "src/" 1441 | } 1442 | }, 1443 | "notification-url": "https://packagist.org/downloads/", 1444 | "license": [ 1445 | "MIT" 1446 | ], 1447 | "authors": [ 1448 | { 1449 | "name": "Bernhard Schussek", 1450 | "email": "bschussek@gmail.com" 1451 | } 1452 | ], 1453 | "description": "Assertions to validate method input/output with nice error messages.", 1454 | "keywords": [ 1455 | "assert", 1456 | "check", 1457 | "validate" 1458 | ], 1459 | "time": "2016-11-23T20:04:58+00:00" 1460 | } 1461 | ], 1462 | "packages-dev": [], 1463 | "aliases": [], 1464 | "minimum-stability": "stable", 1465 | "stability-flags": [], 1466 | "prefer-stable": false, 1467 | "prefer-lowest": false, 1468 | "platform": [], 1469 | "platform-dev": [] 1470 | } 1471 | -------------------------------------------------------------------------------- /test/project-stub/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | tests 13 | 14 | 15 | 16 | 17 | src 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/project-stub/sub-directory/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /test/project-stub/sub-directory/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calebporzio/sub-directory", 3 | "authors": [ 4 | { 5 | "name": "Caleb Porzio", 6 | "email": "calebporzio@gmail.com" 7 | } 8 | ], 9 | "require": { 10 | "phpunit/phpunit": "^6.4" 11 | }, 12 | "config": { 13 | "allow-plugins": { 14 | "pestphp/pest-plugin": true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/project-stub/sub-directory/composer.json.pest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calebporzio/project-stub", 3 | "description": "Test environment for Better PHPUnit VS Code extension", 4 | "authors": [ 5 | { 6 | "name": "Caleb Porzio", 7 | "email": "calebporzio@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "pestphp/pest": "^2.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/project-stub/sub-directory/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "99143bf78e1b01b82ecdc8ec802df61f", 8 | "packages": [ 9 | { 10 | "name": "doctrine/instantiator", 11 | "version": "1.1.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/instantiator.git", 15 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 20 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.1" 25 | }, 26 | "require-dev": { 27 | "athletic/athletic": "~0.1.8", 28 | "ext-pdo": "*", 29 | "ext-phar": "*", 30 | "phpunit/phpunit": "^6.2.3", 31 | "squizlabs/php_codesniffer": "^3.0.2" 32 | }, 33 | "type": "library", 34 | "extra": { 35 | "branch-alias": { 36 | "dev-master": "1.2.x-dev" 37 | } 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 42 | } 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "MIT" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Marco Pivetta", 51 | "email": "ocramius@gmail.com", 52 | "homepage": "http://ocramius.github.com/" 53 | } 54 | ], 55 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 56 | "homepage": "https://github.com/doctrine/instantiator", 57 | "keywords": [ 58 | "constructor", 59 | "instantiate" 60 | ], 61 | "time": "2017-07-22T11:58:36+00:00" 62 | }, 63 | { 64 | "name": "myclabs/deep-copy", 65 | "version": "1.7.0", 66 | "source": { 67 | "type": "git", 68 | "url": "https://github.com/myclabs/DeepCopy.git", 69 | "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" 70 | }, 71 | "dist": { 72 | "type": "zip", 73 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", 74 | "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", 75 | "shasum": "" 76 | }, 77 | "require": { 78 | "php": "^5.6 || ^7.0" 79 | }, 80 | "require-dev": { 81 | "doctrine/collections": "^1.0", 82 | "doctrine/common": "^2.6", 83 | "phpunit/phpunit": "^4.1" 84 | }, 85 | "type": "library", 86 | "autoload": { 87 | "psr-4": { 88 | "DeepCopy\\": "src/DeepCopy/" 89 | }, 90 | "files": [ 91 | "src/DeepCopy/deep_copy.php" 92 | ] 93 | }, 94 | "notification-url": "https://packagist.org/downloads/", 95 | "license": [ 96 | "MIT" 97 | ], 98 | "description": "Create deep copies (clones) of your objects", 99 | "keywords": [ 100 | "clone", 101 | "copy", 102 | "duplicate", 103 | "object", 104 | "object graph" 105 | ], 106 | "time": "2017-10-19T19:58:43+00:00" 107 | }, 108 | { 109 | "name": "phar-io/manifest", 110 | "version": "1.0.1", 111 | "source": { 112 | "type": "git", 113 | "url": "https://github.com/phar-io/manifest.git", 114 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" 115 | }, 116 | "dist": { 117 | "type": "zip", 118 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", 119 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", 120 | "shasum": "" 121 | }, 122 | "require": { 123 | "ext-dom": "*", 124 | "ext-phar": "*", 125 | "phar-io/version": "^1.0.1", 126 | "php": "^5.6 || ^7.0" 127 | }, 128 | "type": "library", 129 | "extra": { 130 | "branch-alias": { 131 | "dev-master": "1.0.x-dev" 132 | } 133 | }, 134 | "autoload": { 135 | "classmap": [ 136 | "src/" 137 | ] 138 | }, 139 | "notification-url": "https://packagist.org/downloads/", 140 | "license": [ 141 | "BSD-3-Clause" 142 | ], 143 | "authors": [ 144 | { 145 | "name": "Arne Blankerts", 146 | "email": "arne@blankerts.de", 147 | "role": "Developer" 148 | }, 149 | { 150 | "name": "Sebastian Heuer", 151 | "email": "sebastian@phpeople.de", 152 | "role": "Developer" 153 | }, 154 | { 155 | "name": "Sebastian Bergmann", 156 | "email": "sebastian@phpunit.de", 157 | "role": "Developer" 158 | } 159 | ], 160 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 161 | "time": "2017-03-05T18:14:27+00:00" 162 | }, 163 | { 164 | "name": "phar-io/version", 165 | "version": "1.0.1", 166 | "source": { 167 | "type": "git", 168 | "url": "https://github.com/phar-io/version.git", 169 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" 170 | }, 171 | "dist": { 172 | "type": "zip", 173 | "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", 174 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", 175 | "shasum": "" 176 | }, 177 | "require": { 178 | "php": "^5.6 || ^7.0" 179 | }, 180 | "type": "library", 181 | "autoload": { 182 | "classmap": [ 183 | "src/" 184 | ] 185 | }, 186 | "notification-url": "https://packagist.org/downloads/", 187 | "license": [ 188 | "BSD-3-Clause" 189 | ], 190 | "authors": [ 191 | { 192 | "name": "Arne Blankerts", 193 | "email": "arne@blankerts.de", 194 | "role": "Developer" 195 | }, 196 | { 197 | "name": "Sebastian Heuer", 198 | "email": "sebastian@phpeople.de", 199 | "role": "Developer" 200 | }, 201 | { 202 | "name": "Sebastian Bergmann", 203 | "email": "sebastian@phpunit.de", 204 | "role": "Developer" 205 | } 206 | ], 207 | "description": "Library for handling version information and constraints", 208 | "time": "2017-03-05T17:38:23+00:00" 209 | }, 210 | { 211 | "name": "phpdocumentor/reflection-common", 212 | "version": "1.0.1", 213 | "source": { 214 | "type": "git", 215 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 216 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 217 | }, 218 | "dist": { 219 | "type": "zip", 220 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 221 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 222 | "shasum": "" 223 | }, 224 | "require": { 225 | "php": ">=5.5" 226 | }, 227 | "require-dev": { 228 | "phpunit/phpunit": "^4.6" 229 | }, 230 | "type": "library", 231 | "extra": { 232 | "branch-alias": { 233 | "dev-master": "1.0.x-dev" 234 | } 235 | }, 236 | "autoload": { 237 | "psr-4": { 238 | "phpDocumentor\\Reflection\\": [ 239 | "src" 240 | ] 241 | } 242 | }, 243 | "notification-url": "https://packagist.org/downloads/", 244 | "license": [ 245 | "MIT" 246 | ], 247 | "authors": [ 248 | { 249 | "name": "Jaap van Otterdijk", 250 | "email": "opensource@ijaap.nl" 251 | } 252 | ], 253 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 254 | "homepage": "http://www.phpdoc.org", 255 | "keywords": [ 256 | "FQSEN", 257 | "phpDocumentor", 258 | "phpdoc", 259 | "reflection", 260 | "static analysis" 261 | ], 262 | "time": "2017-09-11T18:02:19+00:00" 263 | }, 264 | { 265 | "name": "phpdocumentor/reflection-docblock", 266 | "version": "4.1.1", 267 | "source": { 268 | "type": "git", 269 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 270 | "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2" 271 | }, 272 | "dist": { 273 | "type": "zip", 274 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2", 275 | "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2", 276 | "shasum": "" 277 | }, 278 | "require": { 279 | "php": "^7.0", 280 | "phpdocumentor/reflection-common": "^1.0@dev", 281 | "phpdocumentor/type-resolver": "^0.4.0", 282 | "webmozart/assert": "^1.0" 283 | }, 284 | "require-dev": { 285 | "mockery/mockery": "^0.9.4", 286 | "phpunit/phpunit": "^4.4" 287 | }, 288 | "type": "library", 289 | "autoload": { 290 | "psr-4": { 291 | "phpDocumentor\\Reflection\\": [ 292 | "src/" 293 | ] 294 | } 295 | }, 296 | "notification-url": "https://packagist.org/downloads/", 297 | "license": [ 298 | "MIT" 299 | ], 300 | "authors": [ 301 | { 302 | "name": "Mike van Riel", 303 | "email": "me@mikevanriel.com" 304 | } 305 | ], 306 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 307 | "time": "2017-08-30T18:51:59+00:00" 308 | }, 309 | { 310 | "name": "phpdocumentor/type-resolver", 311 | "version": "0.4.0", 312 | "source": { 313 | "type": "git", 314 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 315 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 316 | }, 317 | "dist": { 318 | "type": "zip", 319 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 320 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 321 | "shasum": "" 322 | }, 323 | "require": { 324 | "php": "^5.5 || ^7.0", 325 | "phpdocumentor/reflection-common": "^1.0" 326 | }, 327 | "require-dev": { 328 | "mockery/mockery": "^0.9.4", 329 | "phpunit/phpunit": "^5.2||^4.8.24" 330 | }, 331 | "type": "library", 332 | "extra": { 333 | "branch-alias": { 334 | "dev-master": "1.0.x-dev" 335 | } 336 | }, 337 | "autoload": { 338 | "psr-4": { 339 | "phpDocumentor\\Reflection\\": [ 340 | "src/" 341 | ] 342 | } 343 | }, 344 | "notification-url": "https://packagist.org/downloads/", 345 | "license": [ 346 | "MIT" 347 | ], 348 | "authors": [ 349 | { 350 | "name": "Mike van Riel", 351 | "email": "me@mikevanriel.com" 352 | } 353 | ], 354 | "time": "2017-07-14T14:27:02+00:00" 355 | }, 356 | { 357 | "name": "phpspec/prophecy", 358 | "version": "v1.7.2", 359 | "source": { 360 | "type": "git", 361 | "url": "https://github.com/phpspec/prophecy.git", 362 | "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" 363 | }, 364 | "dist": { 365 | "type": "zip", 366 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", 367 | "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", 368 | "shasum": "" 369 | }, 370 | "require": { 371 | "doctrine/instantiator": "^1.0.2", 372 | "php": "^5.3|^7.0", 373 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 374 | "sebastian/comparator": "^1.1|^2.0", 375 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 376 | }, 377 | "require-dev": { 378 | "phpspec/phpspec": "^2.5|^3.2", 379 | "phpunit/phpunit": "^4.8 || ^5.6.5" 380 | }, 381 | "type": "library", 382 | "extra": { 383 | "branch-alias": { 384 | "dev-master": "1.7.x-dev" 385 | } 386 | }, 387 | "autoload": { 388 | "psr-0": { 389 | "Prophecy\\": "src/" 390 | } 391 | }, 392 | "notification-url": "https://packagist.org/downloads/", 393 | "license": [ 394 | "MIT" 395 | ], 396 | "authors": [ 397 | { 398 | "name": "Konstantin Kudryashov", 399 | "email": "ever.zet@gmail.com", 400 | "homepage": "http://everzet.com" 401 | }, 402 | { 403 | "name": "Marcello Duarte", 404 | "email": "marcello.duarte@gmail.com" 405 | } 406 | ], 407 | "description": "Highly opinionated mocking framework for PHP 5.3+", 408 | "homepage": "https://github.com/phpspec/prophecy", 409 | "keywords": [ 410 | "Double", 411 | "Dummy", 412 | "fake", 413 | "mock", 414 | "spy", 415 | "stub" 416 | ], 417 | "time": "2017-09-04T11:05:03+00:00" 418 | }, 419 | { 420 | "name": "phpunit/php-code-coverage", 421 | "version": "5.2.3", 422 | "source": { 423 | "type": "git", 424 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 425 | "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d" 426 | }, 427 | "dist": { 428 | "type": "zip", 429 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", 430 | "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d", 431 | "shasum": "" 432 | }, 433 | "require": { 434 | "ext-dom": "*", 435 | "ext-xmlwriter": "*", 436 | "php": "^7.0", 437 | "phpunit/php-file-iterator": "^1.4.2", 438 | "phpunit/php-text-template": "^1.2.1", 439 | "phpunit/php-token-stream": "^2.0", 440 | "sebastian/code-unit-reverse-lookup": "^1.0.1", 441 | "sebastian/environment": "^3.0", 442 | "sebastian/version": "^2.0.1", 443 | "theseer/tokenizer": "^1.1" 444 | }, 445 | "require-dev": { 446 | "ext-xdebug": "^2.5", 447 | "phpunit/phpunit": "^6.0" 448 | }, 449 | "suggest": { 450 | "ext-xdebug": "^2.5.5" 451 | }, 452 | "type": "library", 453 | "extra": { 454 | "branch-alias": { 455 | "dev-master": "5.2.x-dev" 456 | } 457 | }, 458 | "autoload": { 459 | "classmap": [ 460 | "src/" 461 | ] 462 | }, 463 | "notification-url": "https://packagist.org/downloads/", 464 | "license": [ 465 | "BSD-3-Clause" 466 | ], 467 | "authors": [ 468 | { 469 | "name": "Sebastian Bergmann", 470 | "email": "sb@sebastian-bergmann.de", 471 | "role": "lead" 472 | } 473 | ], 474 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 475 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 476 | "keywords": [ 477 | "coverage", 478 | "testing", 479 | "xunit" 480 | ], 481 | "time": "2017-11-03T13:47:33+00:00" 482 | }, 483 | { 484 | "name": "phpunit/php-file-iterator", 485 | "version": "1.4.2", 486 | "source": { 487 | "type": "git", 488 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 489 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" 490 | }, 491 | "dist": { 492 | "type": "zip", 493 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 494 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 495 | "shasum": "" 496 | }, 497 | "require": { 498 | "php": ">=5.3.3" 499 | }, 500 | "type": "library", 501 | "extra": { 502 | "branch-alias": { 503 | "dev-master": "1.4.x-dev" 504 | } 505 | }, 506 | "autoload": { 507 | "classmap": [ 508 | "src/" 509 | ] 510 | }, 511 | "notification-url": "https://packagist.org/downloads/", 512 | "license": [ 513 | "BSD-3-Clause" 514 | ], 515 | "authors": [ 516 | { 517 | "name": "Sebastian Bergmann", 518 | "email": "sb@sebastian-bergmann.de", 519 | "role": "lead" 520 | } 521 | ], 522 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 523 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 524 | "keywords": [ 525 | "filesystem", 526 | "iterator" 527 | ], 528 | "time": "2016-10-03T07:40:28+00:00" 529 | }, 530 | { 531 | "name": "phpunit/php-text-template", 532 | "version": "1.2.1", 533 | "source": { 534 | "type": "git", 535 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 536 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 537 | }, 538 | "dist": { 539 | "type": "zip", 540 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 541 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 542 | "shasum": "" 543 | }, 544 | "require": { 545 | "php": ">=5.3.3" 546 | }, 547 | "type": "library", 548 | "autoload": { 549 | "classmap": [ 550 | "src/" 551 | ] 552 | }, 553 | "notification-url": "https://packagist.org/downloads/", 554 | "license": [ 555 | "BSD-3-Clause" 556 | ], 557 | "authors": [ 558 | { 559 | "name": "Sebastian Bergmann", 560 | "email": "sebastian@phpunit.de", 561 | "role": "lead" 562 | } 563 | ], 564 | "description": "Simple template engine.", 565 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 566 | "keywords": [ 567 | "template" 568 | ], 569 | "time": "2015-06-21T13:50:34+00:00" 570 | }, 571 | { 572 | "name": "phpunit/php-timer", 573 | "version": "1.0.9", 574 | "source": { 575 | "type": "git", 576 | "url": "https://github.com/sebastianbergmann/php-timer.git", 577 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 578 | }, 579 | "dist": { 580 | "type": "zip", 581 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 582 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 583 | "shasum": "" 584 | }, 585 | "require": { 586 | "php": "^5.3.3 || ^7.0" 587 | }, 588 | "require-dev": { 589 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 590 | }, 591 | "type": "library", 592 | "extra": { 593 | "branch-alias": { 594 | "dev-master": "1.0-dev" 595 | } 596 | }, 597 | "autoload": { 598 | "classmap": [ 599 | "src/" 600 | ] 601 | }, 602 | "notification-url": "https://packagist.org/downloads/", 603 | "license": [ 604 | "BSD-3-Clause" 605 | ], 606 | "authors": [ 607 | { 608 | "name": "Sebastian Bergmann", 609 | "email": "sb@sebastian-bergmann.de", 610 | "role": "lead" 611 | } 612 | ], 613 | "description": "Utility class for timing", 614 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 615 | "keywords": [ 616 | "timer" 617 | ], 618 | "time": "2017-02-26T11:10:40+00:00" 619 | }, 620 | { 621 | "name": "phpunit/php-token-stream", 622 | "version": "2.0.1", 623 | "source": { 624 | "type": "git", 625 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 626 | "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0" 627 | }, 628 | "dist": { 629 | "type": "zip", 630 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0", 631 | "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0", 632 | "shasum": "" 633 | }, 634 | "require": { 635 | "ext-tokenizer": "*", 636 | "php": "^7.0" 637 | }, 638 | "require-dev": { 639 | "phpunit/phpunit": "^6.2.4" 640 | }, 641 | "type": "library", 642 | "extra": { 643 | "branch-alias": { 644 | "dev-master": "2.0-dev" 645 | } 646 | }, 647 | "autoload": { 648 | "classmap": [ 649 | "src/" 650 | ] 651 | }, 652 | "notification-url": "https://packagist.org/downloads/", 653 | "license": [ 654 | "BSD-3-Clause" 655 | ], 656 | "authors": [ 657 | { 658 | "name": "Sebastian Bergmann", 659 | "email": "sebastian@phpunit.de" 660 | } 661 | ], 662 | "description": "Wrapper around PHP's tokenizer extension.", 663 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 664 | "keywords": [ 665 | "tokenizer" 666 | ], 667 | "time": "2017-08-20T05:47:52+00:00" 668 | }, 669 | { 670 | "name": "phpunit/phpunit", 671 | "version": "6.4.4", 672 | "source": { 673 | "type": "git", 674 | "url": "https://github.com/sebastianbergmann/phpunit.git", 675 | "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932" 676 | }, 677 | "dist": { 678 | "type": "zip", 679 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/562f7dc75d46510a4ed5d16189ae57fbe45a9932", 680 | "reference": "562f7dc75d46510a4ed5d16189ae57fbe45a9932", 681 | "shasum": "" 682 | }, 683 | "require": { 684 | "ext-dom": "*", 685 | "ext-json": "*", 686 | "ext-libxml": "*", 687 | "ext-mbstring": "*", 688 | "ext-xml": "*", 689 | "myclabs/deep-copy": "^1.6.1", 690 | "phar-io/manifest": "^1.0.1", 691 | "phar-io/version": "^1.0", 692 | "php": "^7.0", 693 | "phpspec/prophecy": "^1.7", 694 | "phpunit/php-code-coverage": "^5.2.2", 695 | "phpunit/php-file-iterator": "^1.4.2", 696 | "phpunit/php-text-template": "^1.2.1", 697 | "phpunit/php-timer": "^1.0.9", 698 | "phpunit/phpunit-mock-objects": "^4.0.3", 699 | "sebastian/comparator": "^2.0.2", 700 | "sebastian/diff": "^2.0", 701 | "sebastian/environment": "^3.1", 702 | "sebastian/exporter": "^3.1", 703 | "sebastian/global-state": "^2.0", 704 | "sebastian/object-enumerator": "^3.0.3", 705 | "sebastian/resource-operations": "^1.0", 706 | "sebastian/version": "^2.0.1" 707 | }, 708 | "conflict": { 709 | "phpdocumentor/reflection-docblock": "3.0.2", 710 | "phpunit/dbunit": "<3.0" 711 | }, 712 | "require-dev": { 713 | "ext-pdo": "*" 714 | }, 715 | "suggest": { 716 | "ext-xdebug": "*", 717 | "phpunit/php-invoker": "^1.1" 718 | }, 719 | "bin": [ 720 | "phpunit" 721 | ], 722 | "type": "library", 723 | "extra": { 724 | "branch-alias": { 725 | "dev-master": "6.4.x-dev" 726 | } 727 | }, 728 | "autoload": { 729 | "classmap": [ 730 | "src/" 731 | ] 732 | }, 733 | "notification-url": "https://packagist.org/downloads/", 734 | "license": [ 735 | "BSD-3-Clause" 736 | ], 737 | "authors": [ 738 | { 739 | "name": "Sebastian Bergmann", 740 | "email": "sebastian@phpunit.de", 741 | "role": "lead" 742 | } 743 | ], 744 | "description": "The PHP Unit Testing framework.", 745 | "homepage": "https://phpunit.de/", 746 | "keywords": [ 747 | "phpunit", 748 | "testing", 749 | "xunit" 750 | ], 751 | "time": "2017-11-08T11:26:09+00:00" 752 | }, 753 | { 754 | "name": "phpunit/phpunit-mock-objects", 755 | "version": "4.0.4", 756 | "source": { 757 | "type": "git", 758 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 759 | "reference": "2f789b59ab89669015ad984afa350c4ec577ade0" 760 | }, 761 | "dist": { 762 | "type": "zip", 763 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/2f789b59ab89669015ad984afa350c4ec577ade0", 764 | "reference": "2f789b59ab89669015ad984afa350c4ec577ade0", 765 | "shasum": "" 766 | }, 767 | "require": { 768 | "doctrine/instantiator": "^1.0.5", 769 | "php": "^7.0", 770 | "phpunit/php-text-template": "^1.2.1", 771 | "sebastian/exporter": "^3.0" 772 | }, 773 | "conflict": { 774 | "phpunit/phpunit": "<6.0" 775 | }, 776 | "require-dev": { 777 | "phpunit/phpunit": "^6.0" 778 | }, 779 | "suggest": { 780 | "ext-soap": "*" 781 | }, 782 | "type": "library", 783 | "extra": { 784 | "branch-alias": { 785 | "dev-master": "4.0.x-dev" 786 | } 787 | }, 788 | "autoload": { 789 | "classmap": [ 790 | "src/" 791 | ] 792 | }, 793 | "notification-url": "https://packagist.org/downloads/", 794 | "license": [ 795 | "BSD-3-Clause" 796 | ], 797 | "authors": [ 798 | { 799 | "name": "Sebastian Bergmann", 800 | "email": "sb@sebastian-bergmann.de", 801 | "role": "lead" 802 | } 803 | ], 804 | "description": "Mock Object library for PHPUnit", 805 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 806 | "keywords": [ 807 | "mock", 808 | "xunit" 809 | ], 810 | "time": "2017-08-03T14:08:16+00:00" 811 | }, 812 | { 813 | "name": "sebastian/code-unit-reverse-lookup", 814 | "version": "1.0.1", 815 | "source": { 816 | "type": "git", 817 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 818 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 819 | }, 820 | "dist": { 821 | "type": "zip", 822 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 823 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 824 | "shasum": "" 825 | }, 826 | "require": { 827 | "php": "^5.6 || ^7.0" 828 | }, 829 | "require-dev": { 830 | "phpunit/phpunit": "^5.7 || ^6.0" 831 | }, 832 | "type": "library", 833 | "extra": { 834 | "branch-alias": { 835 | "dev-master": "1.0.x-dev" 836 | } 837 | }, 838 | "autoload": { 839 | "classmap": [ 840 | "src/" 841 | ] 842 | }, 843 | "notification-url": "https://packagist.org/downloads/", 844 | "license": [ 845 | "BSD-3-Clause" 846 | ], 847 | "authors": [ 848 | { 849 | "name": "Sebastian Bergmann", 850 | "email": "sebastian@phpunit.de" 851 | } 852 | ], 853 | "description": "Looks up which function or method a line of code belongs to", 854 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 855 | "time": "2017-03-04T06:30:41+00:00" 856 | }, 857 | { 858 | "name": "sebastian/comparator", 859 | "version": "2.1.0", 860 | "source": { 861 | "type": "git", 862 | "url": "https://github.com/sebastianbergmann/comparator.git", 863 | "reference": "1174d9018191e93cb9d719edec01257fc05f8158" 864 | }, 865 | "dist": { 866 | "type": "zip", 867 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1174d9018191e93cb9d719edec01257fc05f8158", 868 | "reference": "1174d9018191e93cb9d719edec01257fc05f8158", 869 | "shasum": "" 870 | }, 871 | "require": { 872 | "php": "^7.0", 873 | "sebastian/diff": "^2.0", 874 | "sebastian/exporter": "^3.1" 875 | }, 876 | "require-dev": { 877 | "phpunit/phpunit": "^6.4" 878 | }, 879 | "type": "library", 880 | "extra": { 881 | "branch-alias": { 882 | "dev-master": "2.1.x-dev" 883 | } 884 | }, 885 | "autoload": { 886 | "classmap": [ 887 | "src/" 888 | ] 889 | }, 890 | "notification-url": "https://packagist.org/downloads/", 891 | "license": [ 892 | "BSD-3-Clause" 893 | ], 894 | "authors": [ 895 | { 896 | "name": "Jeff Welch", 897 | "email": "whatthejeff@gmail.com" 898 | }, 899 | { 900 | "name": "Volker Dusch", 901 | "email": "github@wallbash.com" 902 | }, 903 | { 904 | "name": "Bernhard Schussek", 905 | "email": "bschussek@2bepublished.at" 906 | }, 907 | { 908 | "name": "Sebastian Bergmann", 909 | "email": "sebastian@phpunit.de" 910 | } 911 | ], 912 | "description": "Provides the functionality to compare PHP values for equality", 913 | "homepage": "https://github.com/sebastianbergmann/comparator", 914 | "keywords": [ 915 | "comparator", 916 | "compare", 917 | "equality" 918 | ], 919 | "time": "2017-11-03T07:16:52+00:00" 920 | }, 921 | { 922 | "name": "sebastian/diff", 923 | "version": "2.0.1", 924 | "source": { 925 | "type": "git", 926 | "url": "https://github.com/sebastianbergmann/diff.git", 927 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" 928 | }, 929 | "dist": { 930 | "type": "zip", 931 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 932 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 933 | "shasum": "" 934 | }, 935 | "require": { 936 | "php": "^7.0" 937 | }, 938 | "require-dev": { 939 | "phpunit/phpunit": "^6.2" 940 | }, 941 | "type": "library", 942 | "extra": { 943 | "branch-alias": { 944 | "dev-master": "2.0-dev" 945 | } 946 | }, 947 | "autoload": { 948 | "classmap": [ 949 | "src/" 950 | ] 951 | }, 952 | "notification-url": "https://packagist.org/downloads/", 953 | "license": [ 954 | "BSD-3-Clause" 955 | ], 956 | "authors": [ 957 | { 958 | "name": "Kore Nordmann", 959 | "email": "mail@kore-nordmann.de" 960 | }, 961 | { 962 | "name": "Sebastian Bergmann", 963 | "email": "sebastian@phpunit.de" 964 | } 965 | ], 966 | "description": "Diff implementation", 967 | "homepage": "https://github.com/sebastianbergmann/diff", 968 | "keywords": [ 969 | "diff" 970 | ], 971 | "time": "2017-08-03T08:09:46+00:00" 972 | }, 973 | { 974 | "name": "sebastian/environment", 975 | "version": "3.1.0", 976 | "source": { 977 | "type": "git", 978 | "url": "https://github.com/sebastianbergmann/environment.git", 979 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" 980 | }, 981 | "dist": { 982 | "type": "zip", 983 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 984 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 985 | "shasum": "" 986 | }, 987 | "require": { 988 | "php": "^7.0" 989 | }, 990 | "require-dev": { 991 | "phpunit/phpunit": "^6.1" 992 | }, 993 | "type": "library", 994 | "extra": { 995 | "branch-alias": { 996 | "dev-master": "3.1.x-dev" 997 | } 998 | }, 999 | "autoload": { 1000 | "classmap": [ 1001 | "src/" 1002 | ] 1003 | }, 1004 | "notification-url": "https://packagist.org/downloads/", 1005 | "license": [ 1006 | "BSD-3-Clause" 1007 | ], 1008 | "authors": [ 1009 | { 1010 | "name": "Sebastian Bergmann", 1011 | "email": "sebastian@phpunit.de" 1012 | } 1013 | ], 1014 | "description": "Provides functionality to handle HHVM/PHP environments", 1015 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1016 | "keywords": [ 1017 | "Xdebug", 1018 | "environment", 1019 | "hhvm" 1020 | ], 1021 | "time": "2017-07-01T08:51:00+00:00" 1022 | }, 1023 | { 1024 | "name": "sebastian/exporter", 1025 | "version": "3.1.0", 1026 | "source": { 1027 | "type": "git", 1028 | "url": "https://github.com/sebastianbergmann/exporter.git", 1029 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" 1030 | }, 1031 | "dist": { 1032 | "type": "zip", 1033 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", 1034 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", 1035 | "shasum": "" 1036 | }, 1037 | "require": { 1038 | "php": "^7.0", 1039 | "sebastian/recursion-context": "^3.0" 1040 | }, 1041 | "require-dev": { 1042 | "ext-mbstring": "*", 1043 | "phpunit/phpunit": "^6.0" 1044 | }, 1045 | "type": "library", 1046 | "extra": { 1047 | "branch-alias": { 1048 | "dev-master": "3.1.x-dev" 1049 | } 1050 | }, 1051 | "autoload": { 1052 | "classmap": [ 1053 | "src/" 1054 | ] 1055 | }, 1056 | "notification-url": "https://packagist.org/downloads/", 1057 | "license": [ 1058 | "BSD-3-Clause" 1059 | ], 1060 | "authors": [ 1061 | { 1062 | "name": "Jeff Welch", 1063 | "email": "whatthejeff@gmail.com" 1064 | }, 1065 | { 1066 | "name": "Volker Dusch", 1067 | "email": "github@wallbash.com" 1068 | }, 1069 | { 1070 | "name": "Bernhard Schussek", 1071 | "email": "bschussek@2bepublished.at" 1072 | }, 1073 | { 1074 | "name": "Sebastian Bergmann", 1075 | "email": "sebastian@phpunit.de" 1076 | }, 1077 | { 1078 | "name": "Adam Harvey", 1079 | "email": "aharvey@php.net" 1080 | } 1081 | ], 1082 | "description": "Provides the functionality to export PHP variables for visualization", 1083 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1084 | "keywords": [ 1085 | "export", 1086 | "exporter" 1087 | ], 1088 | "time": "2017-04-03T13:19:02+00:00" 1089 | }, 1090 | { 1091 | "name": "sebastian/global-state", 1092 | "version": "2.0.0", 1093 | "source": { 1094 | "type": "git", 1095 | "url": "https://github.com/sebastianbergmann/global-state.git", 1096 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" 1097 | }, 1098 | "dist": { 1099 | "type": "zip", 1100 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1101 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 1102 | "shasum": "" 1103 | }, 1104 | "require": { 1105 | "php": "^7.0" 1106 | }, 1107 | "require-dev": { 1108 | "phpunit/phpunit": "^6.0" 1109 | }, 1110 | "suggest": { 1111 | "ext-uopz": "*" 1112 | }, 1113 | "type": "library", 1114 | "extra": { 1115 | "branch-alias": { 1116 | "dev-master": "2.0-dev" 1117 | } 1118 | }, 1119 | "autoload": { 1120 | "classmap": [ 1121 | "src/" 1122 | ] 1123 | }, 1124 | "notification-url": "https://packagist.org/downloads/", 1125 | "license": [ 1126 | "BSD-3-Clause" 1127 | ], 1128 | "authors": [ 1129 | { 1130 | "name": "Sebastian Bergmann", 1131 | "email": "sebastian@phpunit.de" 1132 | } 1133 | ], 1134 | "description": "Snapshotting of global state", 1135 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1136 | "keywords": [ 1137 | "global state" 1138 | ], 1139 | "time": "2017-04-27T15:39:26+00:00" 1140 | }, 1141 | { 1142 | "name": "sebastian/object-enumerator", 1143 | "version": "3.0.3", 1144 | "source": { 1145 | "type": "git", 1146 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1147 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" 1148 | }, 1149 | "dist": { 1150 | "type": "zip", 1151 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1152 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1153 | "shasum": "" 1154 | }, 1155 | "require": { 1156 | "php": "^7.0", 1157 | "sebastian/object-reflector": "^1.1.1", 1158 | "sebastian/recursion-context": "^3.0" 1159 | }, 1160 | "require-dev": { 1161 | "phpunit/phpunit": "^6.0" 1162 | }, 1163 | "type": "library", 1164 | "extra": { 1165 | "branch-alias": { 1166 | "dev-master": "3.0.x-dev" 1167 | } 1168 | }, 1169 | "autoload": { 1170 | "classmap": [ 1171 | "src/" 1172 | ] 1173 | }, 1174 | "notification-url": "https://packagist.org/downloads/", 1175 | "license": [ 1176 | "BSD-3-Clause" 1177 | ], 1178 | "authors": [ 1179 | { 1180 | "name": "Sebastian Bergmann", 1181 | "email": "sebastian@phpunit.de" 1182 | } 1183 | ], 1184 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1185 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1186 | "time": "2017-08-03T12:35:26+00:00" 1187 | }, 1188 | { 1189 | "name": "sebastian/object-reflector", 1190 | "version": "1.1.1", 1191 | "source": { 1192 | "type": "git", 1193 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1194 | "reference": "773f97c67f28de00d397be301821b06708fca0be" 1195 | }, 1196 | "dist": { 1197 | "type": "zip", 1198 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", 1199 | "reference": "773f97c67f28de00d397be301821b06708fca0be", 1200 | "shasum": "" 1201 | }, 1202 | "require": { 1203 | "php": "^7.0" 1204 | }, 1205 | "require-dev": { 1206 | "phpunit/phpunit": "^6.0" 1207 | }, 1208 | "type": "library", 1209 | "extra": { 1210 | "branch-alias": { 1211 | "dev-master": "1.1-dev" 1212 | } 1213 | }, 1214 | "autoload": { 1215 | "classmap": [ 1216 | "src/" 1217 | ] 1218 | }, 1219 | "notification-url": "https://packagist.org/downloads/", 1220 | "license": [ 1221 | "BSD-3-Clause" 1222 | ], 1223 | "authors": [ 1224 | { 1225 | "name": "Sebastian Bergmann", 1226 | "email": "sebastian@phpunit.de" 1227 | } 1228 | ], 1229 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1230 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1231 | "time": "2017-03-29T09:07:27+00:00" 1232 | }, 1233 | { 1234 | "name": "sebastian/recursion-context", 1235 | "version": "3.0.0", 1236 | "source": { 1237 | "type": "git", 1238 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1239 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" 1240 | }, 1241 | "dist": { 1242 | "type": "zip", 1243 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1244 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1245 | "shasum": "" 1246 | }, 1247 | "require": { 1248 | "php": "^7.0" 1249 | }, 1250 | "require-dev": { 1251 | "phpunit/phpunit": "^6.0" 1252 | }, 1253 | "type": "library", 1254 | "extra": { 1255 | "branch-alias": { 1256 | "dev-master": "3.0.x-dev" 1257 | } 1258 | }, 1259 | "autoload": { 1260 | "classmap": [ 1261 | "src/" 1262 | ] 1263 | }, 1264 | "notification-url": "https://packagist.org/downloads/", 1265 | "license": [ 1266 | "BSD-3-Clause" 1267 | ], 1268 | "authors": [ 1269 | { 1270 | "name": "Jeff Welch", 1271 | "email": "whatthejeff@gmail.com" 1272 | }, 1273 | { 1274 | "name": "Sebastian Bergmann", 1275 | "email": "sebastian@phpunit.de" 1276 | }, 1277 | { 1278 | "name": "Adam Harvey", 1279 | "email": "aharvey@php.net" 1280 | } 1281 | ], 1282 | "description": "Provides functionality to recursively process PHP variables", 1283 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1284 | "time": "2017-03-03T06:23:57+00:00" 1285 | }, 1286 | { 1287 | "name": "sebastian/resource-operations", 1288 | "version": "1.0.0", 1289 | "source": { 1290 | "type": "git", 1291 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1292 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1293 | }, 1294 | "dist": { 1295 | "type": "zip", 1296 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1297 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1298 | "shasum": "" 1299 | }, 1300 | "require": { 1301 | "php": ">=5.6.0" 1302 | }, 1303 | "type": "library", 1304 | "extra": { 1305 | "branch-alias": { 1306 | "dev-master": "1.0.x-dev" 1307 | } 1308 | }, 1309 | "autoload": { 1310 | "classmap": [ 1311 | "src/" 1312 | ] 1313 | }, 1314 | "notification-url": "https://packagist.org/downloads/", 1315 | "license": [ 1316 | "BSD-3-Clause" 1317 | ], 1318 | "authors": [ 1319 | { 1320 | "name": "Sebastian Bergmann", 1321 | "email": "sebastian@phpunit.de" 1322 | } 1323 | ], 1324 | "description": "Provides a list of PHP built-in functions that operate on resources", 1325 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1326 | "time": "2015-07-28T20:34:47+00:00" 1327 | }, 1328 | { 1329 | "name": "sebastian/version", 1330 | "version": "2.0.1", 1331 | "source": { 1332 | "type": "git", 1333 | "url": "https://github.com/sebastianbergmann/version.git", 1334 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1335 | }, 1336 | "dist": { 1337 | "type": "zip", 1338 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1339 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1340 | "shasum": "" 1341 | }, 1342 | "require": { 1343 | "php": ">=5.6" 1344 | }, 1345 | "type": "library", 1346 | "extra": { 1347 | "branch-alias": { 1348 | "dev-master": "2.0.x-dev" 1349 | } 1350 | }, 1351 | "autoload": { 1352 | "classmap": [ 1353 | "src/" 1354 | ] 1355 | }, 1356 | "notification-url": "https://packagist.org/downloads/", 1357 | "license": [ 1358 | "BSD-3-Clause" 1359 | ], 1360 | "authors": [ 1361 | { 1362 | "name": "Sebastian Bergmann", 1363 | "email": "sebastian@phpunit.de", 1364 | "role": "lead" 1365 | } 1366 | ], 1367 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1368 | "homepage": "https://github.com/sebastianbergmann/version", 1369 | "time": "2016-10-03T07:35:21+00:00" 1370 | }, 1371 | { 1372 | "name": "theseer/tokenizer", 1373 | "version": "1.1.0", 1374 | "source": { 1375 | "type": "git", 1376 | "url": "https://github.com/theseer/tokenizer.git", 1377 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" 1378 | }, 1379 | "dist": { 1380 | "type": "zip", 1381 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", 1382 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", 1383 | "shasum": "" 1384 | }, 1385 | "require": { 1386 | "ext-dom": "*", 1387 | "ext-tokenizer": "*", 1388 | "ext-xmlwriter": "*", 1389 | "php": "^7.0" 1390 | }, 1391 | "type": "library", 1392 | "autoload": { 1393 | "classmap": [ 1394 | "src/" 1395 | ] 1396 | }, 1397 | "notification-url": "https://packagist.org/downloads/", 1398 | "license": [ 1399 | "BSD-3-Clause" 1400 | ], 1401 | "authors": [ 1402 | { 1403 | "name": "Arne Blankerts", 1404 | "email": "arne@blankerts.de", 1405 | "role": "Developer" 1406 | } 1407 | ], 1408 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 1409 | "time": "2017-04-07T12:08:54+00:00" 1410 | }, 1411 | { 1412 | "name": "webmozart/assert", 1413 | "version": "1.2.0", 1414 | "source": { 1415 | "type": "git", 1416 | "url": "https://github.com/webmozart/assert.git", 1417 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" 1418 | }, 1419 | "dist": { 1420 | "type": "zip", 1421 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", 1422 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", 1423 | "shasum": "" 1424 | }, 1425 | "require": { 1426 | "php": "^5.3.3 || ^7.0" 1427 | }, 1428 | "require-dev": { 1429 | "phpunit/phpunit": "^4.6", 1430 | "sebastian/version": "^1.0.1" 1431 | }, 1432 | "type": "library", 1433 | "extra": { 1434 | "branch-alias": { 1435 | "dev-master": "1.3-dev" 1436 | } 1437 | }, 1438 | "autoload": { 1439 | "psr-4": { 1440 | "Webmozart\\Assert\\": "src/" 1441 | } 1442 | }, 1443 | "notification-url": "https://packagist.org/downloads/", 1444 | "license": [ 1445 | "MIT" 1446 | ], 1447 | "authors": [ 1448 | { 1449 | "name": "Bernhard Schussek", 1450 | "email": "bschussek@gmail.com" 1451 | } 1452 | ], 1453 | "description": "Assertions to validate method input/output with nice error messages.", 1454 | "keywords": [ 1455 | "assert", 1456 | "check", 1457 | "validate" 1458 | ], 1459 | "time": "2016-11-23T20:04:58+00:00" 1460 | } 1461 | ], 1462 | "packages-dev": [], 1463 | "aliases": [], 1464 | "minimum-stability": "stable", 1465 | "stability-flags": [], 1466 | "prefer-stable": false, 1467 | "prefer-lowest": false, 1468 | "platform": [], 1469 | "platform-dev": [] 1470 | } 1471 | -------------------------------------------------------------------------------- /test/project-stub/sub-directory/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | tests 13 | 14 | 15 | 16 | 17 | src 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/project-stub/sub-directory/tests/SampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/project-stub/tests/File With Spaces Test.php: -------------------------------------------------------------------------------- 1 | assertTrue(false); 8 | } 9 | } -------------------------------------------------------------------------------- /test/project-stub/tests/OtherTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 8 | } 9 | 10 | public function test_this_method_also_shouldnt_be_run() 11 | { 12 | $this->assertTrue(true); 13 | } 14 | } -------------------------------------------------------------------------------- /test/project-stub/tests/SamplePestTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 8 | } 9 | 10 | public function test_second() 11 | { 12 | $this->assertTrue(true); 13 | } 14 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2020", 5 | "lib": ["es2020"], 6 | "outDir": "out", 7 | "sourceMap": true, 8 | "rootDir": "src", 9 | "strict": true, 10 | }, 11 | "exclude": ["node_modules", ".vscode-test"] 12 | } -------------------------------------------------------------------------------- /vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension. 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `extension.js` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * Press `F5` to open a new window with your extension loaded. 16 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 17 | * Set breakpoints in your code inside `extension.js` to debug your extension. 18 | * Find output from your extension in the debug console. 19 | 20 | ## Make changes 21 | * You can relaunch the extension from the debug toolbar after changing code in `extension.js`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | ## Explore the API 25 | * You can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts`. 26 | 27 | ## Run tests 28 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests`. 29 | * Press `F5` to run the tests in a new window with your extension loaded. 30 | * See the output of the test result in the debug console. 31 | * Make changes to `test/extension.test.js` or create new test files inside the `test` folder. 32 | * By convention, the test runner will only consider files matching the name pattern `**.test.js`. 33 | * You can create folders inside the `test` folder to structure your tests any way you want. 34 | --------------------------------------------------------------------------------