├── .circleci └── config.yml ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── run-docs-test.yml │ ├── run-e2e-tests.yml │ └── run-test.yml ├── .gitignore ├── .npmrc ├── .prettierrc ├── .vscode └── launch.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RELEASE.md ├── appveyor.yml ├── commitlint.config.js ├── docs ├── _extensions │ ├── cli_options.py │ ├── ghissue.py │ ├── ghlink_check.py │ └── specs.py ├── _links.rst ├── _static │ ├── css │ │ └── dredd.css │ └── images │ │ ├── README.md │ │ ├── apiary-tests-tutorial.png │ │ ├── apiary-tests.png │ │ ├── dredd-logo.png │ │ ├── dredd.png │ │ ├── hooks-handler.key │ │ └── hooks-handler.png ├── conf.py ├── data-structures.rst ├── hooks │ ├── go.rst │ ├── index.rst │ ├── js.rst │ ├── new-language.rst │ ├── perl.rst │ ├── php.rst │ ├── python.rst │ ├── ruby.rst │ └── rust.rst ├── how-it-works.rst ├── how-to-guides.rst ├── index.rst ├── installation.rst ├── internals.rst ├── quickstart.rst ├── redirects.yml ├── requirements.txt ├── usage-cli.rst └── usage-js.rst ├── lerna.json ├── package.json ├── packages ├── dredd-transactions │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── compile │ │ ├── compileAnnotation.js │ │ ├── compileTransactionName.js │ │ ├── compileURI │ │ │ ├── compileParams.js │ │ │ ├── expandURItemplate.js │ │ │ ├── index.js │ │ │ └── validateParams.js │ │ ├── detectTransactionExampleNumbers.js │ │ └── index.js │ ├── index.js │ ├── package.json │ ├── parse │ │ └── index.js │ ├── scripts │ │ ├── postpack.js │ │ ├── prepack.js │ │ ├── pretest.js │ │ └── smoke.sh │ └── test │ │ ├── fixtures │ │ ├── apib │ │ │ ├── ambiguous-parameters-annotation.apib │ │ │ ├── annotation-sourcemap-ranges.apib │ │ │ ├── arbitrary-action.apib │ │ │ ├── default-required.apib │ │ │ ├── enum-parameter-example.apib │ │ │ ├── enum-parameter-unlisted-example.apib │ │ │ ├── enum-parameter.apib │ │ │ ├── example-parameters.apib │ │ │ ├── http-headers-multiple.apib │ │ │ ├── http-headers.apib │ │ │ ├── missing-title-annotation.apib │ │ │ ├── multipart-form-data.apib │ │ │ ├── multiple-transaction-examples.apib │ │ │ ├── no-body.apib │ │ │ ├── no-schema.apib │ │ │ ├── no-status.apib │ │ │ ├── not-specified-in-uri-template-annotation.apib │ │ │ ├── one-transaction-example.apib │ │ │ ├── ordinary.apib │ │ │ ├── parameters-inheritance.apib │ │ │ ├── parser-error.apib │ │ │ ├── parser-warning.apib │ │ │ ├── prefer-default.apib │ │ │ ├── prefer-sample.apib │ │ │ ├── response-schema.apib │ │ │ ├── unrecognizable.apib │ │ │ ├── uri-expansion-annotation.apib │ │ │ ├── uri-validation-annotation.apib │ │ │ └── without-sections.apib │ │ ├── index.js │ │ ├── openapi2 │ │ │ ├── ambiguous-parameters-annotation.yml │ │ │ ├── consumes.yml │ │ │ ├── default-required.yml │ │ │ ├── default-response.yml │ │ │ ├── dotted-query-parameters.yml │ │ │ ├── enum-parameter-example.yml │ │ │ ├── enum-parameter-unlisted-example.yml │ │ │ ├── enum-parameter.yml │ │ │ ├── example-parameters.yml │ │ │ ├── http-headers.yml │ │ │ ├── multipart-form-data.yml │ │ │ ├── multiple-responses.yml │ │ │ ├── no-body.yml │ │ │ ├── no-schema.yml │ │ │ ├── not-specified-in-uri-template-annotation.yml │ │ │ ├── ordinary.yml │ │ │ ├── parameters-inheritance.yml │ │ │ ├── parser-error.yml │ │ │ ├── parser-warning.yml │ │ │ ├── prefer-default.yml │ │ │ ├── produces-charset.yml │ │ │ ├── produces-non-json-example.yml │ │ │ ├── produces.yml │ │ │ ├── response-schema.yml │ │ │ ├── security-definitions-multiple-responses.yml │ │ │ ├── security-definitions-transitions.yml │ │ │ ├── uri-expansion-annotation.yml │ │ │ └── uri-validation-annotation.yml │ │ └── openapi3 │ │ │ ├── parser-warning.yml │ │ │ └── proof-of-concept.yml │ │ ├── integration │ │ ├── compile-test.js │ │ ├── compileAPIB-test.js │ │ ├── compileOpenAPI2-test.js │ │ └── compileOpenAPI3-test.js │ │ ├── mocha.opts │ │ ├── schemas │ │ ├── createAnnotationSchema.js │ │ ├── createCompileResultSchema.js │ │ ├── createLocationSchema.js │ │ └── createOriginSchema.js │ │ ├── support.js │ │ └── unit │ │ ├── compile-test.js │ │ ├── compileAnnotation-test.js │ │ ├── compileTransactionName-test.js │ │ ├── compileURI │ │ ├── compileParams-test.js │ │ ├── expandURItemplate-test.js │ │ └── validateParams-test.js │ │ ├── detectTransactionExampleNumbers-test.js │ │ └── parse-test.js └── dredd │ ├── .eslintignore │ ├── .eslintrc.js │ ├── ApiaryReportingApi.apib │ ├── bin │ └── dredd │ ├── features │ ├── hooks-js.feature │ ├── step_definitions │ │ ├── .eslintrc.js │ │ └── hooks-js.js │ └── support │ │ └── world.js │ ├── lib │ ├── CLI.js │ ├── Dredd.js │ ├── Hooks.js │ ├── HooksWorkerClient.js │ ├── TransactionRunner.js │ ├── addHooks.js │ ├── annotationToLoggerInfo.js │ ├── childProcess.js │ ├── compileTransactionName.js │ ├── configUtils.js │ ├── configuration │ │ ├── applyConfiguration.js │ │ ├── applyLoggingOptions.js │ │ ├── index.js │ │ ├── normalizeConfig.js │ │ └── validateConfig.js │ ├── configureReporters.js │ ├── general.ts │ ├── getGoBinary.js │ ├── getProxySettings.js │ ├── hooksLog.js │ ├── ignorePipeErrors.js │ ├── index.js │ ├── init.js │ ├── isURL.ts │ ├── logger.js │ ├── performRequest.js │ ├── prettifyResponse.js │ ├── readLocation.js │ ├── reporters │ │ ├── ApiaryReporter.js │ │ ├── BaseReporter.js │ │ ├── CLIReporter.js │ │ ├── DotReporter.js │ │ ├── HTMLReporter.js │ │ ├── MarkdownReporter.js │ │ ├── NyanReporter.js │ │ ├── XUnitReporter.js │ │ └── reporterOutputLogger.js │ ├── resolveLocations.ts │ ├── resolveModule.ts │ ├── resolvePaths.ts │ ├── sortTransactions.ts │ └── which.js │ ├── options.json │ ├── package.json │ ├── readthedocs.yml │ ├── scripts │ └── smoke.sh │ ├── test │ ├── .eslintrc.js │ ├── fixtures │ │ ├── 531-produces-consumes.yaml │ │ ├── apiDescriptions.js │ │ ├── apiary.apib │ │ ├── arbitrary-action.md │ │ ├── blog │ │ │ ├── apidesc.apib │ │ │ ├── apidesc.openapi2.yaml │ │ │ ├── app.js │ │ │ ├── hooks.apib.js │ │ │ └── hooks.openapi2.js │ │ ├── error-blueprint.apib │ │ ├── error-openapi2.yaml │ │ ├── error-uri-template.apib │ │ ├── groupless-names.js │ │ ├── hooks-glob │ │ │ ├── bar │ │ │ │ ├── b.js │ │ │ │ ├── p.js │ │ │ │ └── z.js │ │ │ ├── baz │ │ │ │ ├── c.js │ │ │ │ └── x.js │ │ │ └── foo │ │ │ │ ├── a.js │ │ │ │ ├── o.js │ │ │ │ └── y.js │ │ ├── hooks-log.coffee │ │ ├── hooks.js │ │ ├── https │ │ │ ├── server.crt │ │ │ └── server.key │ │ ├── image.png │ │ ├── json-schema-draft-7-boolean.apib │ │ ├── json-schema-draft-7.apib │ │ ├── multifile │ │ │ ├── greeting.apib │ │ │ ├── message.apib │ │ │ ├── multifile_hooks.coffee │ │ │ └── name.apib │ │ ├── multiple-examples.apib │ │ ├── multiple-responses.yaml │ │ ├── non-js-hooks.rb │ │ ├── openapi2-multiple-responses.js │ │ ├── openapi2-transaction-names.js │ │ ├── regression-152.coffee │ │ ├── regression-319-354.apib │ │ ├── regression-615.apib │ │ ├── regression-893.yaml │ │ ├── regression-897-body.yaml │ │ ├── regression-897-schema.yaml │ │ ├── request │ │ │ ├── application-json.apib │ │ │ ├── application-octet-stream-hooks.js │ │ │ ├── application-octet-stream.apib │ │ │ ├── application-octet-stream.yaml │ │ │ ├── application-x-www-form-urlencoded.apib │ │ │ ├── application-x-www-form-urlencoded.yaml │ │ │ ├── image-png-hooks.js │ │ │ ├── image-png.apib │ │ │ ├── image-png.yaml │ │ │ ├── multipart-form-data-file.yaml │ │ │ ├── multipart-form-data.apib │ │ │ ├── multipart-form-data.yaml │ │ │ └── text-plain.apib │ │ ├── requiredModule.js │ │ ├── response │ │ │ ├── 204-205-body.apib │ │ │ ├── 204-205-body.yaml │ │ │ ├── binary-assert-body-hooks.js │ │ │ ├── binary-ignore-body-hooks.js │ │ │ ├── binary.apib │ │ │ ├── binary.yaml │ │ │ ├── empty-body-empty-schema.apib │ │ │ ├── empty-body-empty-schema.yaml │ │ │ ├── empty-body-hooks.js │ │ │ ├── empty-body.apib │ │ │ └── empty-body.yaml │ │ ├── sanitation │ │ │ ├── any-content-guard-pattern-matching.apib │ │ │ ├── any-content-guard-pattern-matching.js │ │ │ ├── any-content-pattern-matching.apib │ │ │ ├── any-content-pattern-matching.js │ │ │ ├── entire-request-body.apib │ │ │ ├── entire-request-body.js │ │ │ ├── entire-response-body.apib │ │ │ ├── entire-response-body.js │ │ │ ├── plain-text-response-body.apib │ │ │ ├── plain-text-response-body.js │ │ │ ├── request-body-attribute.apib │ │ │ ├── request-body-attribute.js │ │ │ ├── request-headers.apib │ │ │ ├── request-headers.js │ │ │ ├── response-body-attribute.apib │ │ │ ├── response-body-attribute.js │ │ │ ├── response-headers.apib │ │ │ ├── response-headers.js │ │ │ ├── transaction-erroring-hooks.apib │ │ │ ├── transaction-erroring-hooks.js │ │ │ ├── transaction-marked-failed-after.apib │ │ │ ├── transaction-marked-failed-after.js │ │ │ ├── transaction-marked-failed-before.apib │ │ │ ├── transaction-marked-failed-before.js │ │ │ ├── transaction-marked-skipped.apib │ │ │ ├── transaction-marked-skipped.js │ │ │ ├── transaction-passing.apib │ │ │ ├── transaction-passing.js │ │ │ ├── transaction-secured-erroring-hooks.apib │ │ │ ├── transaction-secured-erroring-hooks.js │ │ │ ├── uri-parameters.apib │ │ │ └── uri-parameters.js │ │ ├── schema.apib │ │ ├── scripts │ │ │ ├── dummy-server-crash.js │ │ │ ├── dummy-server-ignore-term.js │ │ │ ├── dummy-server-kill.js │ │ │ ├── dummy-server.js │ │ │ ├── emptyfile │ │ │ ├── endless-ignore-term.coffee │ │ │ ├── exit-0.coffee │ │ │ ├── exit-3.js │ │ │ ├── handle-windows-sigint.js │ │ │ ├── kill-self.js │ │ │ ├── stderr.coffee │ │ │ ├── stdout-exit-3.coffee │ │ │ └── stdout.coffee │ │ ├── simple-unnamed.apib │ │ ├── single-get-nogroup.apib │ │ ├── single-get-path.apib │ │ ├── single-get-uri-template.apib │ │ ├── single-get.apib │ │ ├── single-get.yaml │ │ ├── test2_all.js │ │ ├── test2_events.js │ │ ├── test2_hooks.js │ │ ├── test_all.coffee │ │ ├── test_events.js │ │ ├── test_hooks.coffee │ │ ├── warning-ambiguous.apib │ │ ├── warning-blueprint.apib │ │ └── warning-openapi2.yaml │ ├── integration │ │ ├── annotations-test.js │ │ ├── apiary-reporter-test.js │ │ ├── childProcess-test.js │ │ ├── cli │ │ │ ├── api-blueprint-cli-test.js │ │ │ ├── api-description-cli-test.js │ │ │ ├── configuration-cli-test.js │ │ │ ├── hookfiles-cli-test.js │ │ │ ├── openapi2-cli-test.js │ │ │ ├── reporters-cli-test.js │ │ │ └── server-process-cli-test.js │ │ ├── configuration │ │ │ └── resolveConfig-test.js │ │ ├── helpers.js │ │ ├── js-interface-test.js │ │ ├── json-schema-draft-7-test.js │ │ ├── loading-api-descriptions-test.js │ │ ├── openapi2-test.js │ │ ├── proxy-test.js │ │ ├── regressions │ │ │ ├── regression-152-test.js │ │ │ ├── regression-319-354-test.js │ │ │ ├── regression-531-test.js │ │ │ ├── regression-615-test.js │ │ │ └── regression-893-897-test.js │ │ ├── request-test.js │ │ ├── require-test.js │ │ ├── response-test.js │ │ └── sanitation-test.js │ ├── mocha.opts │ ├── ts-node.js │ ├── tsconfig.json │ └── unit │ │ ├── CLI-test.js │ │ ├── Hooks-test.js │ │ ├── HooksWorkerClient-test.js │ │ ├── addHooks-test.js │ │ ├── annotationToLoggerInfo-test.js │ │ ├── configUtils-test.js │ │ ├── configuration-test.js │ │ ├── configuration │ │ └── normalizeConfig-test.js │ │ ├── configureReporters-test.js │ │ ├── getGoBinary-test.js │ │ ├── getProxySettings-test.js │ │ ├── hooksLog-test.js │ │ ├── init │ │ ├── applyAnswers-test.js │ │ ├── detectApiDescription-test.js │ │ ├── detectCI-test.js │ │ ├── detectLanguage-test.js │ │ ├── detectServer-test.js │ │ ├── printClosingMessage-test.js │ │ ├── updateAppVeyor-test.js │ │ ├── updateCircleCI-test.js │ │ ├── updateTravisCI-test.js │ │ └── updateWercker-test.js │ │ ├── isURL-test.js │ │ ├── performRequest │ │ ├── createTransactionResponse-test.js │ │ ├── detectBodyEncoding-test.js │ │ ├── getBodyAsBuffer-test.js │ │ ├── normalizeBodyEncoding-test.js │ │ ├── normalizeContentLengthHeader-test.js │ │ └── performRequest-test.js │ │ ├── prettifyResponse-test.js │ │ ├── reporters │ │ ├── ApiaryReporter-test.js │ │ ├── BaseReporter-test.js │ │ ├── CLIReporter-test.js │ │ ├── DotReporter-test.js │ │ ├── HTMLReporter-test.js │ │ ├── MarkdownReporter-test.js │ │ ├── NyanReporter-test.js │ │ └── XUnitReporter-test.js │ │ ├── resolveLocations-test.js │ │ ├── resolveModule-test.js │ │ ├── resolvePaths-test.js │ │ ├── sortTransactions-test.ts │ │ └── transactionRunner-test.js │ └── tsconfig.json ├── scripts └── commitlint.sh └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior. How do you call the dredd command? Which command line options? 12 | 13 | **Expected behavior** 14 | A clear and concise description of what you expected to happen. 15 | 16 | **What is in your `dredd.yml`?** 17 | 18 | ```yaml 19 | ( paste your dredd.yml contents here ) 20 | ``` 21 | 22 | **What's your `dredd --version` output?** 23 | 24 | ``` 25 | ( paste your output here ) 26 | ``` 27 | 28 | **Does `dredd --loglevel=debug` uncover something?** 29 | If you run Dredd with debugging output, do you see any interesting information relevant to the bug? 30 | 31 | **Can you send us failing test in a Pull Request?** 32 | We'll gladly help you to contribute; answering yes raises the chances the issue gets fixed. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | #### :rocket: Why this change? 3 | 4 | #### :memo: Related issues and Pull Requests 5 | 6 | #### :white_check_mark: What didn't I forget? 7 | 8 | 11 | 12 | - [ ] To write docs 13 | - [ ] To write tests 14 | - [ ] To put [Conventional Changelog](https://dredd.org/en/latest/internals.html#sem-rel) prefixes in front of all my commits and run `npm run lint` 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "13:00" 8 | open-pull-requests-limit: 10 9 | labels: 10 | - dependencies 11 | ignore: 12 | - dependency-name: nock 13 | versions: 14 | - "> 10.0.6" 15 | - dependency-name: typescript 16 | versions: 17 | - ">= 4.1.a, < 4.2" 18 | - dependency-name: winston 19 | versions: 20 | - "> 2.4.0" 21 | - dependency-name: eslint-config-prettier 22 | versions: 23 | - 7.2.0 24 | - 8.0.0 25 | - 8.1.0 26 | - 8.2.0 27 | - dependency-name: eslint 28 | versions: 29 | - 7.18.0 30 | - 7.19.0 31 | - 7.20.0 32 | - 7.21.0 33 | - 7.22.0 34 | - 7.23.0 35 | - 7.24.0 36 | - dependency-name: "@types/chai" 37 | versions: 38 | - 4.2.14 39 | - 4.2.15 40 | - 4.2.16 41 | commit-message: 42 | prefix: fix 43 | prefix-development: chore 44 | include: scope 45 | - package-ecosystem: pip 46 | directory: "/docs" 47 | schedule: 48 | interval: weekly 49 | time: "13:00" 50 | open-pull-requests-limit: 10 51 | labels: 52 | - dependencies 53 | ignore: 54 | - dependency-name: sphinx 55 | versions: 56 | - 3.5.0 57 | - 3.5.1 58 | - 3.5.2 59 | - 3.5.3 60 | commit-message: 61 | prefix: chore 62 | prefix-development: chore 63 | include: scope 64 | -------------------------------------------------------------------------------- /.github/workflows/run-docs-test.yml: -------------------------------------------------------------------------------- 1 | 2 | name: run-docs-test 3 | 4 | on: push 5 | # here add directory listing on push to test 6 | # paths: 7 | # - /docs/*.rst 8 | # - /docs/**/*.rst 9 | 10 | jobs: 11 | 12 | commitlint: 13 | 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | matrix: 17 | os: [ubuntu-latest] 18 | node-version: [12.x] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | with: 23 | fetch-depth: 0 24 | - run: yarn install 25 | - run: npx commitlint --from HEAD~${{ github.event.pull_request.commits }} --to HEAD 26 | 27 | quality-checks: 28 | 29 | runs-on: ${{ matrix.os }} 30 | 31 | strategy: 32 | matrix: 33 | os: [ubuntu-latest, macos-latest] 34 | node-version: [12.x] 35 | 36 | steps: 37 | - uses: actions/checkout@v2 38 | - name: Use Node.js ${{ matrix.node-version }} 39 | uses: actions/setup-node@v1 40 | - uses: actions/setup-python@v2 41 | with: 42 | python-version: '3.x' 43 | 44 | # venv 45 | - run: pip install -r ./docs/requirements.txt 46 | - run: echo $(python --version) > .python-version 47 | - run: 'if [ ! -d ./venv ]; then python -m venv ./venv; fi' 48 | - run: source $(pwd)/venv/bin/activate 49 | 50 | # install 51 | - run: yarn install 52 | - run: yarn lint 53 | - run: yarn docs:lint 54 | - run: yarn docs:test-extensions 55 | 56 | docs-dry-run: 57 | 58 | runs-on: ${{ matrix.os }} 59 | 60 | strategy: 61 | matrix: 62 | os: [ubuntu-latest, macos-latest] 63 | node-version: [12.x] 64 | 65 | steps: 66 | - uses: actions/checkout@v2 67 | - name: Use Node.js ${{ matrix.node-version }} 68 | uses: actions/setup-node@v1 69 | - uses: actions/setup-python@v2 70 | with: 71 | python-version: '3.x' 72 | 73 | # venv 74 | - run: pip install -r ./docs/requirements.txt 75 | - run: echo $(python --version) > .python-version 76 | - run: 'if [ ! -d ./venv ]; then python -m venv ./venv; fi' 77 | - run: source $(pwd)/venv/bin/activate 78 | 79 | - run: yarn install 80 | - run: yarn docs:build 81 | -------------------------------------------------------------------------------- /.github/workflows/run-e2e-tests.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: run-e2e-tests 5 | 6 | on: push 7 | 8 | jobs: 9 | # e2e tests on api blueprint and swagger 10 | test-e2e-apib: 11 | 12 | runs-on: ${{ matrix.os }} 13 | 14 | strategy: 15 | matrix: 16 | os: [ubuntu-latest, macos-latest] 17 | node-version: [12.x] 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Use Node.js ${{ matrix.node-version }} 22 | uses: actions/setup-node@v1 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | - run: yarn install --frozen-lockfile 26 | - run: yarn build 27 | - run: npx lerna exec --scope="dredd" yarn e2e:apib 28 | 29 | test-e2e-openapi2: 30 | 31 | runs-on: ${{ matrix.os }} 32 | 33 | strategy: 34 | matrix: 35 | os: [ubuntu-latest, macos-latest] 36 | node-version: [12.x] 37 | 38 | steps: 39 | - uses: actions/checkout@v2 40 | - name: Use Node.js ${{ matrix.node-version }} 41 | uses: actions/setup-node@v1 42 | with: 43 | node-version: ${{ matrix.node-version }} 44 | - run: yarn install --frozen-lockfile 45 | - run: yarn build 46 | - run: npx lerna exec --scope="dredd" yarn e2e:openapi2 47 | -------------------------------------------------------------------------------- /.github/workflows/run-test.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: run-test 5 | 6 | on: push 7 | 8 | jobs: 9 | # general test run 10 | test: 11 | 12 | runs-on: ${{ matrix.os }} 13 | 14 | strategy: 15 | matrix: 16 | os: [ubuntu-latest] 17 | node-version: [10.x, 12.x, 14.x] 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Use Node.js ${{ matrix.node-version }} 22 | uses: actions/setup-node@v1 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | - run: yarn install --frozen-lockfile 26 | - run: yarn build 27 | - run: yarn lint 28 | - run: yarn test 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | npm-shrinkwrap.json 3 | 4 | .idea 5 | .vscode 6 | .DS_Store 7 | node_modules 8 | cov.* 9 | *.log 10 | .env* 11 | __pycache__ 12 | /docs/_build 13 | coverage 14 | smoke 15 | build 16 | 17 | # Regardless the rules above, never ignore following 18 | !.vscode/launch.json 19 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact 2 | package-lock=false 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "arrowParens": "always", 7 | "bracketSpacing": true, 8 | "trailingComma": "all" 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "configurations": [ 4 | { 5 | "type": "node", 6 | "request": "attach", 7 | "name": "Attach", 8 | "port": 5858 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Apiary Czech Republic, s.r.o. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Release process 2 | 3 | - [Release reference #1](https://github.com/apiaryio/dredd/pull/1626) 4 | - [Release reference #2](https://github.com/apiaryio/dredd/pull/1862) 5 | 6 | ## 1. Create a release pull request 7 | 8 | ```bash 9 | $ git checkout -b /dredd-14.0.0 10 | $ npx lerna version --no-push --no-git-tag-version 11 | $ git add . 12 | $ git push -u origin /dredd-14.0.0 13 | ``` 14 | 15 | ## 2. Post-merge process 16 | 17 | **Once the release pull request is approved and merged**, proceed using the following instructions: 18 | 19 | ```bash 20 | $ git checkout master 21 | $ git pull 22 | 23 | # Publish the packages respecting their versions from "package.json". 24 | $ npx lerna publish from-package 25 | 26 | # Tag the packages manually with the corresponding next versions. 27 | $ git tag -a -m dredd@14.0.0 dredd@14.0.0 28 | $ git tag -a -m dredd-transactions@10.0.0 dredd-transactions@10.0.0 29 | 30 | # Push the new tags to master. 31 | $ git push --tags 32 | ``` 33 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | nodejs_version: '12' 3 | install: 4 | - ps: Install-Product node 12 5 | - 'npm install -g yarn' 6 | - "set PATH=%APPDATA%\\npm;%PATH%" 7 | - 'yarn install' 8 | cache: 9 | - 'node_modules -> yarn.lock' 10 | - "%APPDATA%\\npm-cache -> yarn.lock" 11 | build: off 12 | test_script: 13 | - 'node --version' 14 | - 'npm --version' 15 | - 'yarn --version' 16 | - 'yarn build' 17 | - 'yarn test' 18 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | ignores: [(message) => /^Bumps \[.+]\(.+\) from .+ to .+\./m.test(message)], 4 | }; 5 | -------------------------------------------------------------------------------- /docs/_extensions/cli_options.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | from textwrap import dedent 4 | 5 | from docutils import nodes 6 | from docutils.statemachine import ViewList 7 | from docutils.parsers.rst import Directive 8 | from jinja2 import Template 9 | from sphinx.util.nodes import nested_parse_with_titles 10 | 11 | 12 | # https://docutils.readthedocs.io/en/sphinx-docs/howto/rst-directives.html 13 | class CLIOptionsDirective(Directive): 14 | required_arguments = 1 15 | 16 | def run(self): 17 | # Load options from given JSON file 18 | options_path = os.path.join( 19 | os.path.dirname(self.state.document['source']), 20 | self.arguments[0], 21 | ) 22 | with open(options_path) as f: 23 | options = json.load(f) 24 | 25 | # Generate reStructuredText markup 26 | rst = '' 27 | for name, attrs in sorted(options.items()): 28 | data = { 29 | 'name': name, 30 | 'alias': attrs.get('alias'), 31 | 'default': json.dumps(attrs['default']) if 'default' in attrs else None, 32 | 'description': attrs['description'], 33 | } 34 | template = Template(dedent(''' 35 | .. _{{ name }}{% if alias %}-{{ alias }}{% endif %}: 36 | 37 | .. option:: --{{ name }}{% if alias %}, -{{ alias }}{% endif %} 38 | 39 | {{ description }} 40 | {% if default %}**Default value:** ``{{ default }}``{% endif %} 41 | 42 | ''')) 43 | rst += template.render(**data) 44 | 45 | # Generate docutils nodes 46 | result = ViewList() 47 | for line in rst.splitlines(): 48 | result.append(line, f'') 49 | node = nodes.section(document=self.state.document) 50 | nested_parse_with_titles(self.state, result, node) 51 | return node.children 52 | 53 | 54 | def setup(app): 55 | app.add_directive('cli-options', CLIOptionsDirective) 56 | return {'version': '1.0', 'parallel_read_safe': True} 57 | -------------------------------------------------------------------------------- /docs/_links.rst: -------------------------------------------------------------------------------- 1 | .. _Apiary: https://apiary.io 2 | .. _Dredd: https://dredd.org 3 | .. _Gavel: https://github.com/apiaryio/gavel.js 4 | .. _Dredd Transactions: https://github.com/apiaryio/dredd-transactions 5 | 6 | 7 | .. API Blueprint 8 | 9 | .. _API Blueprint: https://apiblueprint.org 10 | .. _MSON: https://apiblueprint.org/documentation/mson/tutorial.html 11 | 12 | 13 | .. OpenAPI specification 14 | 15 | .. _OpenAPI 2: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md 16 | .. _OpenAPI 3: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md 17 | 18 | 19 | .. JSON Schema 20 | 21 | .. _JSON Schema: https://json-schema.org 22 | .. _JSON Schema Draft 4: https://tools.ietf.org/html/draft-zyp-json-schema-04 23 | .. _JSON Schema Draft 5: https://tools.ietf.org/html/draft-wright-json-schema-00 24 | .. _JSON Schema Draft 6: https://tools.ietf.org/html/draft-wright-json-schema-01 25 | .. _JSON Schema Draft 7: https://tools.ietf.org/html/draft-handrews-json-schema-01 26 | 27 | 28 | .. CI 29 | 30 | .. _Travis CI: https://travis-ci.org 31 | .. _CircleCI: https://circleci.com 32 | .. _Jenkins: https://jenkins.io 33 | .. _AppVeyor: https://www.appveyor.com 34 | -------------------------------------------------------------------------------- /docs/_static/css/dredd.css: -------------------------------------------------------------------------------- 1 | /* 2 | Minor tuning to get the Font-Awesome icons used in buttons slightly padded. 3 | */ 4 | .btn .fa { 5 | margin-right: 0.3rem; 6 | } 7 | .btn.float-right .fa { 8 | margin-right: 0; 9 | margin-left: 0.3rem; 10 | } 11 | 12 | /* 13 | The :rfc: role renders bold for no obvious reason. This resets it so 14 | the links don't stand out. 15 | */ 16 | a.rfc strong { 17 | font-weight: normal; 18 | } 19 | 20 | /* 21 | Workaround for https://github.com/djungelorm/sphinx-tabs/pull/35 22 | */ 23 | .rst-content .section ul:last-child, 24 | .rst-content .toctree-wrapper ul:last-child, 25 | article ul:last-child { 26 | margin-bottom: 24px; 27 | } 28 | .rst-content .tab ul:last-child { 29 | margin-bottom: 0; 30 | } 31 | -------------------------------------------------------------------------------- /docs/_static/images/README.md: -------------------------------------------------------------------------------- 1 | # Images directory 2 | 3 | Read more about the files here in Dredd's [internals docs](https://dredd.org/en/latest/internals.html#images). 4 | -------------------------------------------------------------------------------- /docs/_static/images/apiary-tests-tutorial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/docs/_static/images/apiary-tests-tutorial.png -------------------------------------------------------------------------------- /docs/_static/images/apiary-tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/docs/_static/images/apiary-tests.png -------------------------------------------------------------------------------- /docs/_static/images/dredd-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/docs/_static/images/dredd-logo.png -------------------------------------------------------------------------------- /docs/_static/images/dredd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/docs/_static/images/dredd.png -------------------------------------------------------------------------------- /docs/_static/images/hooks-handler.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/docs/_static/images/hooks-handler.key -------------------------------------------------------------------------------- /docs/_static/images/hooks-handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/docs/_static/images/hooks-handler.png -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | # Not using pipenv on purpose as ReadTheDocs do not support it yet 2 | # https://github.com/rtfd/readthedocs.org/issues/3181 3 | 4 | 5 | # dependencies 6 | sphinx==4.3.0 7 | jinja2==3.0.3 8 | git+https://github.com/jhermann/pygments-markdown-lexer.git@e651a9a3f664285b01451eb39232b1ad9af65956#egg=pygments-markdown-lexer 9 | pygments-apiblueprint==0.2.0 10 | sphinx-tabs==3.2.0 11 | sphinx-panels==0.6.0 12 | myst-parser==0.15.2 13 | 14 | # dev dependencies 15 | sphinx-autobuild==2021.3.14 16 | sphinx-rtd-theme==1.0.0 17 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "registry": "https://registry.npmjs.org", 5 | "version": "independent" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "lerna exec --scope=\"*\" yarn build", 5 | "prettify:check": "lerna exec --scope=\"dredd\" yarn prettify:check", 6 | "docs:lint": "sphinx-build -nW -b linkcheck ./docs ./docs/_build", 7 | "docs:test-extensions": "python -m unittest docs/_extensions/*.py --verbose", 8 | "docs:build": "sphinx-build -nW -b html ./docs ./docs/_build", 9 | "docs:serve": "sphinx-autobuild ./docs ./docs/_build", 10 | "commit:lint": "./scripts/commitlint.sh", 11 | "lint": "lerna exec --scope=\"*\" --concurrency=1 --no-bail yarn lint", 12 | "test:smoke": "lerna exec --scope=\"*\" --concurrency=1 --no-bail yarn test:smoke", 13 | "test": "lerna exec --scope=\"*\" --concurrency=1 --no-bail yarn test" 14 | }, 15 | "devDependencies": { 16 | "@commitlint/cli": "11.0.0", 17 | "@commitlint/config-conventional": "11.0.0", 18 | "commitlint-circle": "1.0.0", 19 | "lerna": "^3.22.1" 20 | }, 21 | "workspaces": { 22 | "packages": [ 23 | "packages/*" 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/dredd-transactions/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb-base', 3 | env: { 4 | mocha: true, 5 | node: true, 6 | }, 7 | rules: { 8 | // Node 6 does not support dangling commas in function arguments 9 | 'comma-dangle': [ 10 | 'error', 11 | { 12 | arrays: 'always-multiline', 13 | objects: 'always-multiline', 14 | functions: 'never', 15 | }, 16 | ], 17 | 18 | // This is to allow a convention for exporting functions solely for 19 | // the purpose of the unit tests, see 20 | // https://github.com/apiaryio/dredd-transactions/pull/179#discussion_r206852270 21 | 'no-underscore-dangle': 'off', 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /packages/dredd-transactions/.gitignore: -------------------------------------------------------------------------------- 1 | dredd-transactions-*.tgz 2 | prepack-symlinks.log 3 | /test/fixtures/**/*.json 4 | -------------------------------------------------------------------------------- /packages/dredd-transactions/compile/compileAnnotation.js: -------------------------------------------------------------------------------- 1 | function compileLocation(sourceMapElement) { 2 | try { 3 | const startAttributes = sourceMapElement.first.first.first.attributes; 4 | const endAttributes = sourceMapElement.last.last.last.attributes; 5 | return [ 6 | [ 7 | startAttributes.get('line').toValue(), 8 | startAttributes.get('column').toValue(), 9 | ], 10 | [ 11 | endAttributes.get('line').toValue(), 12 | endAttributes.get('column').toValue(), 13 | ], 14 | ]; 15 | } catch (e) { 16 | return null; 17 | } 18 | } 19 | 20 | 21 | module.exports = function compileAnnotation(annotationElement) { 22 | return { 23 | type: annotationElement.classes.getValue(0), 24 | component: 'apiDescriptionParser', 25 | message: annotationElement.toValue(), 26 | location: compileLocation(annotationElement.attributes.get('sourceMap')), 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /packages/dredd-transactions/compile/compileTransactionName.js: -------------------------------------------------------------------------------- 1 | module.exports = function compileTransactionName(origin) { 2 | return [ 3 | origin.apiName, 4 | origin.resourceGroupName, 5 | origin.resourceName, 6 | origin.actionName, 7 | origin.exampleName, 8 | ] 9 | .filter(Boolean) 10 | .join(' > '); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/dredd-transactions/compile/compileURI/compileParams.js: -------------------------------------------------------------------------------- 1 | function getRequired(memberElement) { 2 | const typeAttributes = memberElement.attributes.getValue('typeAttributes') || []; 3 | return typeAttributes.includes('required'); 4 | } 5 | 6 | 7 | function getDefault(valueElement) { 8 | return valueElement ? valueElement.attributes.getValue('default') : undefined; 9 | } 10 | 11 | 12 | function getExample(valueElement) { 13 | if (valueElement) { 14 | const example = valueElement.toValue(); 15 | 16 | if (typeof example === 'undefined' || example === null) { 17 | const values = valueElement.attributes.getValue('enumerations') || []; 18 | return values[0]; 19 | } 20 | return example; 21 | } 22 | return undefined; 23 | } 24 | 25 | 26 | function getValues(valueElement) { 27 | return valueElement 28 | ? valueElement.attributes.getValue('enumerations') || [] 29 | : []; 30 | } 31 | 32 | 33 | function compileParams(hrefVariablesElement) { 34 | if (!hrefVariablesElement) return {}; 35 | return hrefVariablesElement 36 | .map((valueElement, keyElement, memberElement) => { 37 | const name = keyElement.toValue(); 38 | return { 39 | [name]: { 40 | required: getRequired(memberElement), 41 | default: getDefault(valueElement), 42 | example: getExample(valueElement), 43 | values: getValues(valueElement), 44 | }, 45 | }; 46 | }) 47 | .reduce((params, param) => Object.assign(params, param), {}); 48 | } 49 | 50 | 51 | module.exports = compileParams; 52 | -------------------------------------------------------------------------------- /packages/dredd-transactions/compile/compileURI/index.js: -------------------------------------------------------------------------------- 1 | const compileParams = require('./compileParams'); 2 | const validateParams = require('./validateParams'); 3 | const expandUriTemplate = require('./expandURItemplate'); 4 | 5 | 6 | module.exports = function compileURI(httpRequestElement) { 7 | const annotations = []; 8 | const cascade = [ 9 | httpRequestElement.parents.find('resource'), 10 | httpRequestElement.parents.find('transition'), 11 | httpRequestElement, 12 | ]; 13 | 14 | function overrideParams(params, paramsToOverride = {}) { 15 | const result = Object.assign({}, params); 16 | 17 | Object.keys(paramsToOverride).forEach((paramName) => { 18 | const param = paramsToOverride[paramName]; 19 | result[paramName] = param; 20 | }); 21 | 22 | return result; 23 | } 24 | 25 | // The last non-empty href overrides any previous hrefs 26 | const href = cascade 27 | .map((element) => { 28 | const value = element.href ? element.href.toValue() : undefined; 29 | return value; 30 | }) 31 | .filter(hrefParam => !!hrefParam) 32 | .pop(); 33 | 34 | // Support for 'httpRequest' parameters is experimental. The element does 35 | // not have the '.hrefVariables' convenience property yet. If it's added in 36 | // the future, '.attributes.get('hrefVariables')' can be replaced 37 | // with '.hrefVariables'. 38 | const params = cascade 39 | .map(element => compileParams(element.attributes.get('hrefVariables'))) 40 | .reduce(overrideParams, {}); 41 | 42 | let result = validateParams(params); 43 | let component = 'parametersValidation'; 44 | result.errors.forEach(error => annotations.push({ type: 'error', component, message: error })); 45 | result.warnings.forEach(warning => annotations.push({ type: 'warning', component, message: warning })); 46 | 47 | result = expandUriTemplate(href, params); 48 | component = 'uriTemplateExpansion'; 49 | result.errors.forEach(error => annotations.push({ type: 'error', component, message: error })); 50 | result.warnings.forEach(warning => annotations.push({ type: 'warning', component, message: warning })); 51 | 52 | return { uri: result.uri, annotations }; 53 | }; 54 | -------------------------------------------------------------------------------- /packages/dredd-transactions/compile/compileURI/validateParams.js: -------------------------------------------------------------------------------- 1 | module.exports = function validateParams(params) { 2 | const result = { warnings: [], errors: [] }; 3 | 4 | Object.keys(params).forEach((paramName) => { 5 | let text; 6 | const param = params[paramName]; 7 | 8 | if (param.required && !(typeof param.example !== 'undefined' && param.example !== '') && !(typeof param.default !== 'undefined' && param.default !== '')) { 9 | text = `Required URI parameter '${paramName}' has no example or default value.`; 10 | result.errors.push(text); 11 | } 12 | 13 | switch (param.type) { 14 | case 'number': 15 | if (Number.isNaN(parseFloat(param.example))) { 16 | text = `URI parameter '${paramName}' is declared as 'number' but it is a string.`; 17 | result.errors.push(text); 18 | } 19 | break; 20 | case 'boolean': 21 | if ((param.example !== 'true') && (param.example !== 'false')) { 22 | text = `URI parameter '${paramName}' is declared as 'boolean' but it is not.`; 23 | result.errors.push(text); 24 | } 25 | break; 26 | default: 27 | break; 28 | } 29 | 30 | if (param.values.length > 0) { 31 | if (!(param.values.indexOf(param.example) > -1)) { 32 | text = `URI parameter '${paramName}' example value is not one of enum values.`; 33 | result.errors.push(text); 34 | } 35 | } 36 | }); 37 | 38 | return result; 39 | }; 40 | -------------------------------------------------------------------------------- /packages/dredd-transactions/index.js: -------------------------------------------------------------------------------- 1 | const parse = require('./parse'); 2 | const compile = require('./compile'); 3 | 4 | 5 | module.exports = { parse, compile }; 6 | -------------------------------------------------------------------------------- /packages/dredd-transactions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dredd-transactions", 3 | "version": "10.1.0", 4 | "description": "Compiles HTTP Transactions (Request-Response pairs) from an API description document", 5 | "main": "index.js", 6 | "engines": { 7 | "node": ">=10" 8 | }, 9 | "scripts": { 10 | "prepack": "node ./scripts/prepack.js", 11 | "postpack": "node ./scripts/postpack.js", 12 | "build": "exit 0", 13 | "clean": "rimraf ./coverage", 14 | "lint": "eslint --ignore-path .gitignore .", 15 | "pretest": "node ./scripts/pretest.js", 16 | "test": "npm run clean && mocha ./test", 17 | "test:smoke": "bash ./scripts/smoke.sh" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/apiaryio/dredd" 22 | }, 23 | "files": [ 24 | "parse", 25 | "compile", 26 | "README.md" 27 | ], 28 | "dependencies": { 29 | "@apielements/apib-parser": "0.20.1", 30 | "@apielements/core": "^0.2.1", 31 | "@apielements/openapi2-parser": "0.32.4", 32 | "@apielements/openapi3-parser": "0.16.0", 33 | "uri-template": "1.0.1" 34 | }, 35 | "bundledDependencies": [ 36 | "@apielements/apib-parser" 37 | ], 38 | "devDependencies": { 39 | "chai": "4.3.4", 40 | "chai-json-schema": "1.5.1", 41 | "eslint": "6.8.0", 42 | "eslint-config-airbnb-base": "13.2.0", 43 | "eslint-plugin-import": "2.18.2", 44 | "mocha": "7.1.2", 45 | "mocha-lcov-reporter": "1.3.0", 46 | "proxyquire": "2.1.3", 47 | "rimraf": "3.0.2", 48 | "sinon": "9.2.1" 49 | }, 50 | "keywords": [ 51 | "api", 52 | "test", 53 | "testing", 54 | "documenation", 55 | "integration", 56 | "acceptance" 57 | ], 58 | "author": "Apiary Czech Republic, s.r.o. ", 59 | "license": "MIT", 60 | "homepage": "https://github.com/apiaryio/dredd/tree/master/packages/dredd-transactions" 61 | } 62 | -------------------------------------------------------------------------------- /packages/dredd-transactions/parse/index.js: -------------------------------------------------------------------------------- 1 | const fury = require('@apielements/core'); 2 | 3 | 4 | fury.use(require('@apielements/apib-parser')); 5 | fury.use(require('@apielements/openapi2-parser')); 6 | fury.use(require('@apielements/openapi3-parser')); 7 | 8 | const { Annotation, SourceMap, ParseResult } = fury.minim.elements; 9 | 10 | 11 | function createAnnotation(type, message) { 12 | const element = new Annotation(message); 13 | element.classes.push(type); 14 | element.attributes.set('sourceMap', [ 15 | new SourceMap([[0, 1]]), 16 | ]); 17 | return element; 18 | } 19 | 20 | 21 | function detectMediaType(apiDescription) { 22 | const adapters = fury.detect(apiDescription); 23 | if (adapters.length) { 24 | return { mediaType: adapters[0].mediaTypes[0], fallback: false }; 25 | } 26 | return { mediaType: 'text/vnd.apiblueprint', fallback: true }; 27 | } 28 | 29 | 30 | function parse(apiDescription, callback) { 31 | const { mediaType, fallback } = detectMediaType(apiDescription); 32 | 33 | fury.parse({ 34 | source: apiDescription, 35 | mediaType, 36 | generateSourceMap: true, 37 | }, (err, parseResult) => { 38 | const apiElements = parseResult || new ParseResult([]); 39 | 40 | if (fallback) { 41 | apiElements.unshift(createAnnotation('warning', ( 42 | 'Could not recognize API description format, assuming API Blueprint' 43 | ))); 44 | } 45 | if (err && !parseResult) { 46 | // The condition should be only 'if (err)' 47 | // https://github.com/apiaryio/api-elements.js/issues/167 48 | apiElements.unshift(createAnnotation('error', ( 49 | `Could not parse API description: ${err.message}` 50 | ))); 51 | } 52 | 53 | callback(null, { mediaType, apiElements }); 54 | }); 55 | } 56 | 57 | 58 | module.exports = parse; 59 | -------------------------------------------------------------------------------- /packages/dredd-transactions/scripts/postpack.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Cleans up after the prepack.js script 3 | 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | /* eslint-disable no-console */ 7 | /* eslint-disable-next-line import/no-extraneous-dependencies */ 8 | const rimraf = require('rimraf'); 9 | 10 | const PACKAGE_DIR = path.resolve(path.dirname(__filename), '..'); 11 | const SYMLINKS_LOG = path.join(PACKAGE_DIR, 'prepack-symlinks.log'); 12 | 13 | console.log('cleaning up symlinks...'); 14 | 15 | if (!fs.existsSync(SYMLINKS_LOG)) { 16 | console.log('no configuration present, nothing to clean.'); 17 | process.exit(0); 18 | } 19 | 20 | console.log('found configuration at "%s"', SYMLINKS_LOG); 21 | 22 | const dependencies = fs.readFileSync(SYMLINKS_LOG, 'utf8') 23 | .split('\n') 24 | .filter(line => line.trim()); 25 | console.log('found %d dependencies:\n', dependencies.length, dependencies); 26 | 27 | const dependencyPaths = dependencies 28 | .map(dependencyName => path.join(PACKAGE_DIR, 'node_modules', dependencyName)) 29 | .filter(symlinkPath => fs.existsSync(symlinkPath)); 30 | console.log('resolved dependency paths:', dependencyPaths); 31 | 32 | dependencyPaths.forEach(symlinkPath => rimraf.sync(symlinkPath)); 33 | console.log('successfully unlinked %d symlinks!', dependencyPaths.length); 34 | 35 | rimraf.sync(SYMLINKS_LOG); 36 | console.log('successfully removed "%s"!', SYMLINKS_LOG); 37 | -------------------------------------------------------------------------------- /packages/dredd-transactions/scripts/pretest.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | 6 | const fury = require('@apielements/core'); 7 | 8 | const parse = require('../parse'); 9 | 10 | 11 | const FIXTURES_DIR = path.join(__dirname, '..', 'test', 'fixtures'); 12 | 13 | 14 | function listFixtures(fixturesSubDir) { 15 | return fs.readdirSync(fixturesSubDir) 16 | .map(itemName => path.join(fixturesSubDir, itemName)) 17 | .filter(itemPath => itemPath.endsWith('.apib') || itemPath.endsWith('.yml')); 18 | } 19 | 20 | function getJSONPath(fixturePath) { 21 | const dir = path.dirname(fixturePath); 22 | const basename = path.basename(fixturePath, path.extname(fixturePath)); 23 | return `${path.join(dir, basename)}.json`; 24 | } 25 | 26 | function parseFixture(fixturePath) { 27 | return new Promise((resolve, reject) => { 28 | const fixture = fs.readFileSync(fixturePath, 'utf8'); 29 | parse(fixture, (err, result) => { 30 | if (err) reject(err); 31 | else resolve(result.apiElements); 32 | }); 33 | }).then((apiElements) => { 34 | const jsonPath = getJSONPath(fixturePath); 35 | const json = JSON.stringify(fury.minim.toRefract(apiElements), null, 2); 36 | fs.writeFileSync(jsonPath, json); 37 | }); 38 | } 39 | 40 | 41 | const fixturesPerSubDir = fs.readdirSync(FIXTURES_DIR) 42 | .map(itemName => path.join(FIXTURES_DIR, itemName)) 43 | .filter(itemPath => fs.statSync(itemPath).isDirectory()) 44 | .map(listFixtures); 45 | const fixtures = [].concat(...fixturesPerSubDir); 46 | 47 | console.log(`Parsing ${fixtures.length} fixtures...`); 48 | Promise 49 | .all(fixtures.map(parseFixture)) 50 | .then(() => { console.log('Fixtures ready!'); }) 51 | .catch((err) => { console.error(err); process.exitCode = 1; }); 52 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/ambiguous-parameters-annotation.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey/{id}] 6 | 7 | + Parameters 8 | + id 9 | 10 | ### Remove [DELETE] 11 | 12 | + Response 203 13 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/annotation-sourcemap-ranges.apib: -------------------------------------------------------------------------------- 1 | # API Name 2 | 3 | ## GET / 4 | 5 | + Response 200 (application/json) 6 | 7 | + Body 8 | 9 | {} 10 | 11 | + Schema 12 | 13 | {} 14 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/arbitrary-action.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource [/resource/{id}] 6 | 7 | + Parameters 8 | + id: 1 (number) 9 | 10 | ### Normal Action [GET] 11 | 12 | + Response 200 (text/plain) 13 | 14 | Woof 15 | 16 | ## Arbitrary Action [POST /arbitrary/{param}] 17 | 18 | + Parameters 19 | + param: sample (string) - Parameter not present under resource section. 20 | 21 | + Response 200 (text/plain) 22 | 23 | Moo 24 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/default-required.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper}] 6 | 7 | ### GET 8 | 9 | + Parameters 10 | + beekeeper (string, required) - Beekeeper. 11 | 12 | Description... 13 | 14 | + Default: `Honza` 15 | 16 | + Response 200 17 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/enum-parameter-example.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper}] 6 | 7 | + Parameters 8 | + beekeeper: Honza (enum[string]) 9 | + Members 10 | + Adam 11 | + Honza 12 | 13 | ### Remove [DELETE] 14 | 15 | + Request (application/json) 16 | 17 | + Response 200 18 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/enum-parameter-unlisted-example.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper}] 6 | 7 | + Parameters 8 | + beekeeper: Pavan (enum[string]) 9 | + Members 10 | + Adam 11 | + Honza 12 | 13 | ### Remove [DELETE] 14 | 15 | + Request (application/json) 16 | 17 | + Response 200 18 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/enum-parameter.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper}] 6 | 7 | + Parameters 8 | + beekeeper (enum[string]) 9 | + Members 10 | + Adam 11 | + Honza 12 | 13 | ### Remove [DELETE] 14 | 15 | + Request (application/json) 16 | 17 | + Response 200 18 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/example-parameters.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper,flavour}] 6 | 7 | + Parameters 8 | + beekeeper: Honza (enum[string], optional) 9 | 10 | Description... 11 | 12 | + Members 13 | + Adam 14 | + Honza 15 | + Dredd 16 | + Default: Dredd 17 | 18 | + flavour: spicy (enum[string]) 19 | + Members 20 | + sweet 21 | + spicy 22 | 23 | ### Remove [DELETE] 24 | 25 | + Request (application/json) 26 | 27 | + Response 200 28 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/http-headers-multiple.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | # Honey [/honey] 6 | 7 | ## Retrieve Honey [GET] 8 | 9 | + Request (application/json) 10 | 11 | + Headers 12 | 13 | X-Multiple: foo 14 | X-Multiple: bar 15 | 16 | + Response 200 (application/json) 17 | 18 | + Headers 19 | 20 | Set-Cookie: session-id=123 21 | Set-Cookie: likes-honey=true 22 | 23 | + Body 24 | 25 | {} 26 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/http-headers.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | # Honey [/honey] 6 | 7 | ## Retrieve Honey [GET] 8 | 9 | + Request (application/json) 10 | 11 | + Headers 12 | 13 | Accept: application/json 14 | 15 | + Response 200 (application/json) 16 | 17 | + Headers 18 | 19 | X-Test: Adam 20 | 21 | + Body 22 | 23 | {} 24 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/missing-title-annotation.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | So Long, and Thanks for All the Fish! 4 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/multipart-form-data.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Sanbox 'multipart/form-data' API 4 | 5 | # POST /data 6 | 7 | + Request (multipart/form-data; boundary=CUSTOM-BOUNDARY) 8 | 9 | + Body 10 | 11 | --CUSTOM-BOUNDARY 12 | Content-Disposition: form-data; name="text" 13 | Content-Type: text/plain 14 | 15 | test equals to 42 16 | --CUSTOM-BOUNDARY 17 | Content-Disposition: form-data; name="json" 18 | Content-Type: application/json 19 | 20 | {"test": 42} 21 | 22 | --CUSTOM-BOUNDARY-- 23 | 24 | + Response 200 (multipart/form-data; boundary=CUSTOM-BOUNDARY) 25 | 26 | + Body 27 | 28 | --CUSTOM-BOUNDARY 29 | Content-Disposition: form-data; name="text" 30 | Content-Type: text/plain 31 | 32 | test equals to 42 33 | --CUSTOM-BOUNDARY 34 | Content-Disposition: form-data; name="json" 35 | Content-Type: application/json 36 | 37 | {"test": 42} 38 | 39 | --CUSTOM-BOUNDARY-- 40 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/multiple-transaction-examples.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey] 6 | 7 | ### Retrieve [GET] 8 | 9 | + Request (application/json) 10 | + Response 200 11 | + Response 500 12 | 13 | ### Remove [DELETE] 14 | 15 | + Request (application/json) 16 | + Response 200 17 | + Response 500 18 | 19 | + Request (text/plain) 20 | + Request (application/xml) 21 | + Response 415 22 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/no-body.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource [/resource.json] 6 | 7 | ### Retrieve Representation [GET] 8 | 9 | + Response 200 (application/json) 10 | 11 | ## Resource [/resource.csv] 12 | 13 | ### Retrieve Representation [GET] 14 | 15 | + Response 200 (text/csv) 16 | 17 | + Body 18 | 19 | ``` 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/no-schema.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource [/resource] 6 | 7 | ### Retrieve Representation [GET] 8 | 9 | + Response 200 (application/json) 10 | 11 | ## Resource [/resource.json] 12 | 13 | ### Retrieve Representation [GET] 14 | 15 | + Response 200 (application/json) 16 | 17 | {"name": "Honza", "color": "green"} 18 | 19 | ## Resource [/resource.csv] 20 | 21 | ### Retrieve Representation [GET] 22 | 23 | + Response 200 (text/csv) 24 | 25 | name,color 26 | Honza,green 27 | 28 | ## Resource [/resource.yaml] 29 | 30 | ### Retrieve Representation [GET] 31 | 32 | + Response 200 (text/yaml) 33 | 34 | name: Honza 35 | color: green 36 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/no-status.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource Foo [/foo] 6 | 7 | ### Retrieve Representation [GET] 8 | 9 | + Response (application/json) 10 | + Attributes 11 | name: Honza (string) 12 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/not-specified-in-uri-template-annotation.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey] 6 | 7 | ### Remove [DELETE] 8 | 9 | + Parameters 10 | + beekeeper: Honza (string) 11 | 12 | + Response 203 13 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/one-transaction-example.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey] 6 | 7 | ### Remove [DELETE] 8 | 9 | + Request (application/json) 10 | 11 | + Response 200 12 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/ordinary.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines Collection [/machines] 8 | 9 | ## Create New Machine [POST] 10 | 11 | + Request (application/json) 12 | 13 | { 14 | "type": "bulldozer", 15 | "name": "willy" 16 | } 17 | 18 | + Response 201 (application/json) 19 | 20 | { 21 | "mesage": "Created" 22 | } 23 | 24 | ## List All Machines [GET] 25 | 26 | + Response 200 (application/json) 27 | 28 | [{ 29 | "_id": "52341870ed55224b15ff07ef", 30 | "type": "bulldozer", 31 | "name": "willy" 32 | }] 33 | 34 | # Machine [/machines/{name}] 35 | 36 | + Parameters 37 | + name: willy (required) 38 | 39 | ## Update [PUT] 40 | 41 | + Request (application/json) 42 | 43 | { 44 | "name": "waldo" 45 | } 46 | 47 | + Response 200 (application/json) 48 | 49 | { 50 | "type": "bulldozer", 51 | "name": "waldo", 52 | "_id": "5229c6e8e4b0bd7dbb07e29c" 53 | } 54 | 55 | ## Retrieve [GET] 56 | 57 | + Parameters 58 | + name: waldo (required) 59 | 60 | + Response 200 (text/plain) 61 | 62 | { 63 | "type": "bulldozer", 64 | "name": "waldo", 65 | "_id": "5229c6e8e4b0bd7dbb07e29c" 66 | } 67 | 68 | ## Remove [DELETE] 69 | 70 | + Parameters 71 | + name: waldo (required) 72 | 73 | + Response 204 74 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/parameters-inheritance.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper,amount}] 6 | 7 | + Parameters 8 | + beekeeper: Adam (string) 9 | 10 | ### Remove [DELETE] 11 | 12 | + Parameters 13 | + amount: 42 (number) 14 | 15 | + Request (application/json) 16 | 17 | + Parameters 18 | + beekeeper: Honza 19 | 20 | + Response 200 21 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/parser-error.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Sample API 4 | 5 | ## GET /message 6 | 7 | + Response 200 (text/plain) 8 | 9 | Hello World! 10 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/parser-warning.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Sample API 4 | 5 | ## GET /message 6 | 7 | + Response (text/plain) 8 | 9 | Hello World! 10 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/prefer-default.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper}] 6 | 7 | ### GET 8 | 9 | + Parameters 10 | + beekeeper (string, optional) - Beekeeper. 11 | 12 | Description... 13 | 14 | + Default: `Honza` 15 | 16 | + Members 17 | + `Adam` - Adam K. 18 | + `Pavan` - Pavan S. 19 | + `Honza` - Honza J. 20 | 21 | + Response 200 22 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/prefer-sample.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?beekeeper}] 6 | 7 | ### GET 8 | 9 | + Parameters 10 | + beekeeper: `Pavan` (string, optional) - Beekeeper. 11 | 12 | Description... 13 | 14 | + Default: `Honza` 15 | 16 | + Members 17 | + `Adam` - Adam K. 18 | + `Pavan` - Pavan S. 19 | + `Honza` - Honza J. 20 | 21 | + Response 200 22 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/response-schema.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey] 6 | 7 | ### With Body [POST] 8 | 9 | + Request (application/json) 10 | 11 | + Response 201 12 | + Body 13 | 14 | [] 15 | 16 | + Schema 17 | 18 | {"type": "array"} 19 | 20 | ### Without Body [DELETE] 21 | 22 | + Request (application/json) 23 | 24 | + Response 200 25 | + Schema 26 | 27 | {"type": "array"} 28 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/unrecognizable.apib: -------------------------------------------------------------------------------- 1 | # Sample API 2 | 3 | ## Coupon Base 4 | 5 | + percent_off: 25 (number) 6 | 7 | A positive integer between 1 and 100 that represents the discount the 8 | coupon will apply. 9 | 10 | + redeem_by (number) - Date after which the coupon can no longer be redeemed 11 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/uri-expansion-annotation.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{] 6 | 7 | ### Remove [DELETE] 8 | 9 | + Response 203 10 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/uri-validation-annotation.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey{?param}] 6 | 7 | ### Remove [DELETE] 8 | 9 | + Parameters 10 | + nonexisting (string, required) 11 | 12 | + Response 203 13 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/apib/without-sections.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # GET /message 4 | 5 | + Response 200 (text/plain) 6 | 7 | Hello World! 8 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/ambiguous-parameters-annotation.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: /api 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /pets/{id}: 16 | get: 17 | description: Returns a user based on a single ID, if the user does not have access to the pet 18 | operationId: find pet by id 19 | parameters: 20 | - name: id 21 | in: path 22 | description: ID of pet to fetch 23 | required: true 24 | type: integer 25 | format: int64 26 | responses: 27 | 200: 28 | description: pet response 29 | schema: 30 | $ref: '#/definitions/Pet' 31 | definitions: 32 | Pet: 33 | required: 34 | - id 35 | - name 36 | properties: 37 | id: 38 | type: integer 39 | format: int64 40 | name: 41 | type: string 42 | tag: 43 | type: string 44 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/consumes.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Beehive API 5 | consumes: 6 | - application/json 7 | - application/xml 8 | paths: 9 | /honey: 10 | post: 11 | responses: 12 | 200: 13 | description: pet response 14 | schema: 15 | $ref: '#/definitions/Bee' 16 | /honey-with-override: 17 | post: 18 | consumes: 19 | - application/json 20 | responses: 21 | 200: 22 | description: pet response 23 | schema: 24 | $ref: '#/definitions/Bee' 25 | definitions: 26 | Bee: 27 | required: 28 | - id 29 | - name 30 | properties: 31 | id: 32 | type: integer 33 | format: int64 34 | name: 35 | type: string 36 | tag: 37 | type: string 38 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/default-required.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: / 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /honey: 16 | get: 17 | parameters: 18 | - name: beekeeper 19 | in: query 20 | type: string 21 | required: true 22 | default: Honza 23 | responses: 24 | 200: 25 | description: pet response 26 | schema: 27 | $ref: '#/definitions/Pet' 28 | definitions: 29 | Pet: 30 | required: 31 | - id 32 | - name 33 | properties: 34 | id: 35 | type: integer 36 | format: int64 37 | name: 38 | type: string 39 | tag: 40 | type: string 41 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/default-response.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json 9 | paths: 10 | /foo: 11 | get: 12 | responses: 13 | default: 14 | description: Default Representation 15 | schema: 16 | type: object 17 | properties: 18 | name: 19 | type: string 20 | examples: 21 | application/json: 22 | name: Honza 23 | /bar: 24 | get: 25 | responses: 26 | 204: 27 | description: Representation 28 | default: 29 | description: Default Representation 30 | examples: 31 | application/json: 32 | message: Error 33 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/dotted-query-parameters.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | 3 | info: 4 | version: '1' 5 | title: test 6 | 7 | host: petstore.swagger.io 8 | basePath: /api 9 | 10 | schemes: 11 | - http 12 | 13 | consumes: 14 | - application/json 15 | 16 | paths: 17 | /pets: 18 | get: 19 | description: Get 20 | parameters: 21 | - in: query 22 | name: filter.dotted 23 | type: string 24 | responses: 25 | '200': 26 | description: OK 27 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/enum-parameter-example.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: / 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /honey: 16 | get: 17 | parameters: 18 | - name: beekeeper 19 | in: query 20 | type: string 21 | enum: 22 | - Adam 23 | - Honza 24 | x-example: Honza 25 | responses: 26 | 200: 27 | description: pet response 28 | schema: 29 | $ref: '#/definitions/Pet' 30 | definitions: 31 | Pet: 32 | required: 33 | - id 34 | - name 35 | properties: 36 | id: 37 | type: integer 38 | format: int64 39 | name: 40 | type: string 41 | tag: 42 | type: string 43 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/enum-parameter-unlisted-example.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: / 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /honey: 16 | get: 17 | parameters: 18 | - name: beekeeper 19 | in: query 20 | type: string 21 | enum: 22 | - Adam 23 | - Honza 24 | x-example: Pavan 25 | responses: 26 | 200: 27 | description: pet response 28 | schema: 29 | $ref: '#/definitions/Pet' 30 | definitions: 31 | Pet: 32 | required: 33 | - id 34 | - name 35 | properties: 36 | id: 37 | type: integer 38 | format: int64 39 | name: 40 | type: string 41 | tag: 42 | type: string 43 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/enum-parameter.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: / 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /honey: 16 | get: 17 | parameters: 18 | - name: beekeeper 19 | in: query 20 | type: string 21 | enum: 22 | - Adam 23 | - Honza 24 | responses: 25 | 200: 26 | description: pet response 27 | schema: 28 | $ref: '#/definitions/Pet' 29 | definitions: 30 | Pet: 31 | required: 32 | - id 33 | - name 34 | properties: 35 | id: 36 | type: integer 37 | format: int64 38 | name: 39 | type: string 40 | tag: 41 | type: string 42 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/example-parameters.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: / 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /honey: 16 | get: 17 | parameters: 18 | - name: beekeeper 19 | in: query 20 | type: string 21 | enum: 22 | - Adam 23 | - Honza 24 | - Dredd 25 | x-example: Honza 26 | default: Dredd 27 | - name: flavour 28 | in: query 29 | type: string 30 | enum: 31 | - sweet 32 | - spicy 33 | x-example: spicy 34 | responses: 35 | 200: 36 | description: pet response 37 | schema: 38 | $ref: '#/definitions/Pet' 39 | definitions: 40 | Pet: 41 | required: 42 | - id 43 | - name 44 | properties: 45 | id: 46 | type: integer 47 | format: int64 48 | name: 49 | type: string 50 | tag: 51 | type: string 52 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/http-headers.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Beehive API 5 | consumes: 6 | - application/json 7 | produces: 8 | - application/json 9 | paths: 10 | /honey: 11 | get: 12 | responses: 13 | 200: 14 | description: pet response 15 | headers: 16 | X-Test: 17 | type: string 18 | enum: 19 | - Adam 20 | - Pavan 21 | schema: 22 | $ref: '#/definitions/Bee' 23 | definitions: 24 | Bee: 25 | required: 26 | - id 27 | - name 28 | properties: 29 | id: 30 | type: integer 31 | format: int64 32 | name: 33 | type: string 34 | tag: 35 | type: string 36 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/multipart-form-data.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: "Sanbox 'multipart/form-data' API" 4 | version: '1.0' 5 | consumes: 6 | - multipart/form-data; boundary=CUSTOM-BOUNDARY 7 | produces: 8 | - multipart/form-data; boundary=CUSTOM-BOUNDARY 9 | paths: 10 | '/data': 11 | post: 12 | parameters: 13 | - name: text 14 | in: formData 15 | type: string 16 | required: true 17 | x-example: "test equals to 42" 18 | - name: json 19 | in: formData 20 | type: string 21 | required: true 22 | x-example: '{"test": 42}' 23 | responses: 24 | 200: 25 | description: 'Test' 26 | examples: 27 | multipart/form-data; boundary=CUSTOM-BOUNDARY: | 28 | --CUSTOM-BOUNDARY 29 | Content-Disposition: form-data; name="text" 30 | Content-Type: text/plain 31 | 32 | test equals to 42 33 | --CUSTOM-BOUNDARY 34 | Content-Disposition: form-data; name="json" 35 | Content-Type: application/json 36 | 37 | {"test": 42} 38 | 39 | --CUSTOM-BOUNDARY-- 40 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/multiple-responses.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Beehive API 5 | consumes: 6 | - application/json 7 | produces: 8 | - application/xml 9 | - application/json 10 | paths: 11 | /honey: 12 | get: 13 | responses: 14 | 200: 15 | description: pet response 16 | headers: 17 | X-Test: 18 | type: string 19 | enum: 20 | - Adam 21 | - Pavan 22 | schema: 23 | $ref: '#/definitions/Bee' 24 | 400: 25 | description: user error 26 | 500: 27 | description: server error 28 | definitions: 29 | Bee: 30 | required: 31 | - id 32 | - name 33 | properties: 34 | id: 35 | type: integer 36 | format: int64 37 | name: 38 | type: string 39 | tag: 40 | type: string 41 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/no-body.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json 9 | - text/csv 10 | paths: 11 | /resource.json: 12 | get: 13 | responses: 14 | 200: 15 | description: Representation 16 | /resource.csv: 17 | get: 18 | responses: 19 | 200: 20 | description: Representation 21 | examples: 22 | text/csv: "" 23 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/no-schema.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json 9 | - text/csv 10 | - text/yaml 11 | paths: 12 | /resource: 13 | get: 14 | responses: 15 | 200: 16 | description: Representation 17 | /resource.json: 18 | get: 19 | responses: 20 | 200: 21 | description: Representation 22 | examples: 23 | application/json: 24 | name: "Honza" 25 | color: "green" 26 | /resource.csv: 27 | get: 28 | responses: 29 | 200: 30 | description: Representation 31 | examples: 32 | text/csv: "name,color\nHonza,green\n" 33 | /resource.yaml: 34 | get: 35 | responses: 36 | 200: 37 | description: Representation 38 | examples: 39 | text/yaml: "name: Honza\ncolor: green\n" 40 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/not-specified-in-uri-template-annotation.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: /api 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /pet: 16 | get: 17 | description: Returns a user based on a single ID, if the user does not have access to the pet 18 | operationId: find pet by id 19 | parameters: 20 | - name: id 21 | in: path 22 | description: ID of pet to fetch 23 | required: true 24 | type: integer 25 | format: int64 26 | responses: 27 | 200: 28 | description: pet response 29 | schema: 30 | $ref: '#/definitions/Pet' 31 | definitions: 32 | Pet: 33 | required: 34 | - id 35 | - name 36 | properties: 37 | id: 38 | type: integer 39 | format: int64 40 | name: 41 | type: string 42 | tag: 43 | type: string 44 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/ordinary.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Action 4 | version: '1.0' 5 | paths: 6 | '/test': 7 | head: 8 | summary: Test head 9 | responses: 10 | 204: 11 | description: Test response 12 | options: 13 | summary: Test options 14 | responses: 15 | 204: 16 | description: Test response 17 | get: 18 | summary: Test get 19 | description: Test description 20 | operationId: test 21 | responses: 22 | 204: 23 | description: Test response 24 | post: 25 | summary: Test post 26 | responses: 27 | 204: 28 | description: Test response 29 | put: 30 | summary: Test put 31 | responses: 32 | 204: 33 | description: Test response 34 | patch: 35 | summary: Test patch 36 | responses: 37 | 204: 38 | description: Test response 39 | delete: 40 | summary: Test delete 41 | responses: 42 | 204: 43 | description: Test response 44 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/parameters-inheritance.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: Beehive API 4 | version: "1.0" 5 | paths: 6 | "/honey": 7 | parameters: 8 | - name: beekeeper 9 | in: query 10 | default: Adam 11 | type: string 12 | get: 13 | parameters: 14 | - name: beekeeper 15 | in: query 16 | default: Honza 17 | type: string 18 | - name: amount 19 | in: query 20 | default: 42 21 | type: number 22 | responses: 23 | 204: 24 | description: Sample description 25 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/parser-error.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: Sample API 4 | version: "0.1" 5 | paths: {/pets: 6 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/parser-warning.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Title 4 | version: '1.0' 5 | host: api.example.com 6 | schemes: 7 | - https 8 | - http 9 | securityDefinitions: {} 10 | security: [] 11 | paths: 12 | /foo: 13 | parameters: 14 | - name: theBody 15 | in: body 16 | schema: {} 17 | get: 18 | responses: 19 | 200: 20 | description: Test 21 | examples: 22 | application/json: 23 | status: ok 24 | default: 25 | description: Test 26 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/prefer-default.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: / 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /honey: 16 | get: 17 | parameters: 18 | - name: beekeeper 19 | in: query 20 | type: string 21 | default: Honza 22 | enum: 23 | - Adam 24 | - Pavan 25 | - Honza 26 | responses: 27 | 200: 28 | description: pet response 29 | schema: 30 | $ref: '#/definitions/Pet' 31 | definitions: 32 | Pet: 33 | required: 34 | - id 35 | - name 36 | properties: 37 | id: 38 | type: integer 39 | format: int64 40 | name: 41 | type: string 42 | tag: 43 | type: string 44 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/produces-charset.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: Produces Header With Content-Type Parameters 4 | version: "1.0" 5 | paths: 6 | /test: 7 | get: 8 | produces: 9 | - application/json; charset=utf-8 10 | - application/xml 11 | responses: 12 | 200: 13 | description: Test description 14 | /test-with-override: 15 | get: 16 | produces: 17 | - application/json; charset=utf-8 18 | responses: 19 | 200: 20 | description: Test description when overriding produce content type 21 | headers: 22 | content-type: 23 | type: string 24 | default: text/plain 25 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/produces-non-json-example.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: Produces Non-JSON Content-Type 4 | version: "1.0" 5 | paths: 6 | /test: 7 | get: 8 | produces: 9 | - application/json 10 | - text/plain 11 | responses: 12 | 200: 13 | description: Test description 14 | examples: 15 | 'application/json': {message: 'Hello!'} 16 | 'text/plain': 'Hello!' 17 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/produces.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Produces Header 4 | version: '1.0' 5 | paths: 6 | '/test': 7 | get: 8 | produces: 9 | - application/json 10 | - application/xml 11 | responses: 12 | 200: 13 | description: Test description 14 | '/test-with-override': 15 | get: 16 | produces: 17 | - application/json 18 | responses: 19 | 200: 20 | description: Test description when overriding produce content type 21 | headers: 22 | content-type: 23 | type: string 24 | default: text/plain 25 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/response-schema.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Schema Reference 4 | version: '1.0' 5 | consumes: 6 | - application/json 7 | produces: 8 | - application/json 9 | paths: 10 | '/test': 11 | post: 12 | parameters: 13 | - name: title 14 | in: body 15 | description: Body argument 16 | required: true 17 | schema: 18 | type: string 19 | example: Hello 20 | responses: 21 | 200: 22 | description: Test description 23 | schema: 24 | $ref: '#/definitions/Item' 25 | '/test-without-produces': 26 | get: 27 | produces: [] 28 | responses: 29 | 200: 30 | description: Test description without produces 31 | schema: 32 | $ref: '#/definitions/Item' 33 | definitions: 34 | Item: 35 | type: object 36 | properties: 37 | id: 38 | type: number 39 | enum: [123] 40 | default: 456 41 | name: 42 | type: string 43 | default: Item name 44 | required: ['id', 'name'] 45 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/security-definitions-multiple-responses.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | securityDefinitions: 7 | apiKeyAuth: 8 | type: apiKey 9 | in: header 10 | name: api_key 11 | host: petstore.swagger.io 12 | basePath: / 13 | schemes: 14 | - http 15 | consumes: 16 | - application/json 17 | produces: 18 | - application/json 19 | paths: 20 | /secured-honey: 21 | get: 22 | security: 23 | - apiKeyAuth: [] 24 | responses: 25 | 200: 26 | description: pet response 27 | schema: 28 | $ref: '#/definitions/Pet' 29 | 500: 30 | description: server error 31 | definitions: 32 | Pet: 33 | required: 34 | - id 35 | - name 36 | properties: 37 | id: 38 | type: integer 39 | format: int64 40 | name: 41 | type: string 42 | tag: 43 | type: string 44 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/security-definitions-transitions.yml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | version: '1.0.0' 4 | title: Swagger Oauth2 Implicit 5 | securityDefinitions: 6 | customOauth2: 7 | type: oauth2 8 | flow: implicit 9 | authorizationUrl: "http://example.com/oauth/authorize" 10 | scopes: 11 | scope1: Test Scope 1 12 | scope2: Test Scope 2 13 | paths: 14 | /endpoint: 15 | get: 16 | security: 17 | - customOauth2: 18 | - scope1 19 | - scope2 20 | responses: 21 | 200: 22 | description: With Security 23 | schema: 24 | type: string 25 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/uri-expansion-annotation.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: /api 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /pets/{: 16 | get: 17 | responses: 18 | 200: 19 | description: pet response 20 | schema: 21 | $ref: '#/definitions/Pet' 22 | definitions: 23 | Pet: 24 | required: 25 | - id 26 | - name 27 | properties: 28 | id: 29 | type: integer 30 | format: int64 31 | name: 32 | type: string 33 | tag: 34 | type: string 35 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi2/uri-validation-annotation.yml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Petstore 5 | description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification 6 | host: petstore.swagger.io 7 | basePath: /api 8 | schemes: 9 | - http 10 | consumes: 11 | - application/json 12 | produces: 13 | - application/json 14 | paths: 15 | /pets/{id}: 16 | get: 17 | description: Returns a user based on a single ID, if the user does not have access to the pet 18 | operationId: find pet by id 19 | parameters: 20 | - name: id 21 | in: path 22 | description: ID of pet to fetch 23 | required: true 24 | type: integer 25 | format: int64 26 | responses: 27 | 200: 28 | description: pet response 29 | schema: 30 | $ref: '#/definitions/Pet' 31 | definitions: 32 | Pet: 33 | required: 34 | - id 35 | - name 36 | properties: 37 | id: 38 | type: integer 39 | format: int64 40 | name: 41 | type: string 42 | tag: 43 | type: string 44 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/fixtures/openapi3/parser-warning.yml: -------------------------------------------------------------------------------- 1 | openapi: "3.0.0" 2 | info: 3 | version: "1.0.0" 4 | title: Title 5 | paths: 6 | /: 7 | get: 8 | summary: Summary 9 | foo: {} 10 | responses: 11 | "200": 12 | description: "Success" 13 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/integration/compileOpenAPI3-test.js: -------------------------------------------------------------------------------- 1 | const createCompileResultSchema = require('../schemas/createCompileResultSchema'); 2 | 3 | const { assert, fixtures } = require('../support'); 4 | const compile = require('../../compile'); 5 | 6 | 7 | describe('compile() · OpenAPI 3', () => { 8 | describe('ordinary, valid API description', () => { 9 | const { mediaType, apiElements } = fixtures('proof-of-concept').openapi3; 10 | const compileResult = compile(mediaType, apiElements); 11 | 12 | it('produces some annotation and some transactions', () => { 13 | assert.jsonSchema(compileResult, createCompileResultSchema({ 14 | annotations: [1], 15 | transactions: [1], 16 | })); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/mocha.opts: -------------------------------------------------------------------------------- 1 | --watch-extensions=js 2 | --recursive 3 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/schemas/createAnnotationSchema.js: -------------------------------------------------------------------------------- 1 | const createLocationSchema = require('./createLocationSchema'); 2 | const createOriginSchema = require('./createOriginSchema'); 3 | 4 | const TYPES = ['error', 'warning']; 5 | 6 | 7 | module.exports = function createAnnotationSchema(options = {}) { 8 | // Either filename string or undefined (= doesn't matter) 9 | const { filename } = options; 10 | 11 | // options.message should be substring or RegExp 12 | const messageSchema = { type: 'string' }; 13 | if (options.message) { messageSchema.pattern = options.message; } 14 | 15 | const parseAnnotationSchema = { 16 | type: 'object', 17 | properties: { 18 | type: { 19 | type: 'string', 20 | enum: options.type ? [options.type] : TYPES, 21 | }, 22 | component: { 23 | type: 'string', 24 | enum: ['apiDescriptionParser'], 25 | }, 26 | message: messageSchema, 27 | location: createLocationSchema(), 28 | }, 29 | required: ['type', 'component', 'message', 'location'], 30 | additionalProperties: false, 31 | }; 32 | if (options.component === 'apiDescriptionParser') { 33 | return parseAnnotationSchema; 34 | } 35 | 36 | const compileAnnotationSchema = { 37 | type: 'object', 38 | properties: { 39 | type: { 40 | type: 'string', 41 | enum: options.type ? [options.type] : TYPES, 42 | }, 43 | component: { 44 | type: 'string', 45 | enum: options.component ? [options.component] : ['parametersValidation', 'uriTemplateExpansion'], 46 | }, 47 | message: messageSchema, 48 | location: { type: 'null' }, // https://github.com/apiaryio/dredd-transactions/issues/275 49 | name: { type: 'string' }, 50 | origin: createOriginSchema({ filename }), 51 | }, 52 | required: ['type', 'component', 'message', 'location', 'name', 'origin'], 53 | additionalProperties: false, 54 | }; 55 | if (['parametersValidation', 'uriTemplateExpansion'].includes(options.component)) { 56 | return compileAnnotationSchema; 57 | } 58 | 59 | return { anyOf: [parseAnnotationSchema, compileAnnotationSchema] }; 60 | }; 61 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/schemas/createLocationSchema.js: -------------------------------------------------------------------------------- 1 | const position = { 2 | type: 'array', 3 | items: [ 4 | { type: 'number' }, 5 | { type: 'number' }, 6 | ], 7 | additionalItems: false, 8 | }; 9 | 10 | module.exports = () => ({ 11 | anyOf: [ 12 | { 13 | type: 'array', 14 | items: [position, position], 15 | additionalItems: false, 16 | }, 17 | { 18 | type: 'null', 19 | }, 20 | ], 21 | }); 22 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/schemas/createOriginSchema.js: -------------------------------------------------------------------------------- 1 | module.exports = function createOriginSchema(options = {}) { 2 | let filenameSchema; 3 | if (options.filename) { 4 | filenameSchema = { type: 'string', enum: [options.filename] }; 5 | } else { 6 | filenameSchema = { type: 'string' }; 7 | } 8 | 9 | return { 10 | type: 'object', 11 | properties: { 12 | filename: filenameSchema, 13 | apiName: { type: 'string' }, 14 | resourceGroupName: { type: 'string' }, 15 | resourceName: { type: 'string' }, 16 | actionName: { type: 'string' }, 17 | exampleName: { type: 'string' }, 18 | }, 19 | required: ['filename', 'apiName', 'resourceGroupName', 'resourceName', 'actionName', 'exampleName'], 20 | additionalProperties: false, 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/support.js: -------------------------------------------------------------------------------- 1 | const chai = require('chai'); 2 | const chaiJSONschema = require('chai-json-schema'); 3 | 4 | const fixtures = require('./fixtures'); 5 | 6 | 7 | chai.use(chaiJSONschema); 8 | 9 | 10 | module.exports = { assert: chai.assert, fixtures }; 11 | -------------------------------------------------------------------------------- /packages/dredd-transactions/test/unit/compileTransactionName-test.js: -------------------------------------------------------------------------------- 1 | const { assert } = require('chai'); 2 | 3 | const compileTransactionName = require('../../compile/compileTransactionName'); 4 | 5 | 6 | describe('compileTransactionName()', () => { 7 | it('is a function', () => assert.isFunction(compileTransactionName)); 8 | 9 | it('joins all parts of the origin object', () => { 10 | const name = compileTransactionName({ 11 | apiName: 'a', 12 | resourceGroupName: 'b', 13 | resourceName: 'c', 14 | actionName: 'd', 15 | exampleName: 'e', 16 | }); 17 | assert.equal(name, 'a > b > c > d > e'); 18 | }); 19 | 20 | it('joins just the parts of the origin object, which are available', () => { 21 | const name = compileTransactionName({ 22 | apiName: null, 23 | resourceGroupName: 'a', 24 | resourceName: undefined, 25 | actionName: 'b', 26 | exampleName: '', 27 | }); 28 | assert.equal(name, 'a > b'); 29 | }); 30 | 31 | it('returns no separators if the origin object contains just one part', () => { 32 | const name = compileTransactionName({ 33 | apiName: null, 34 | resourceGroupName: 'a', 35 | resourceName: undefined, 36 | actionName: '', 37 | exampleName: '', 38 | }); 39 | assert.equal(name, 'a'); 40 | }); 41 | 42 | it('does not mind if any part of the origin object already contains the separator', () => { 43 | const name = compileTransactionName({ 44 | apiName: 'a', 45 | resourceGroupName: 'b', 46 | resourceName: 'c', 47 | actionName: 'd', 48 | exampleName: 'e > f', 49 | }); 50 | assert.equal(name, 'a > b > c > d > e > f'); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /packages/dredd/.eslintignore: -------------------------------------------------------------------------------- 1 | .github 2 | .vscode 3 | build 4 | coverage 5 | docs 6 | 7 | # In case Python virtualenv is present in the project directory, this ignores 8 | # its contents (some Python projects vendor JavaScript files, etc.) 9 | site-packages 10 | -------------------------------------------------------------------------------- /packages/dredd/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['airbnb-base', 'prettier'], 3 | env: { 4 | node: true, 5 | }, 6 | rules: { 7 | // Using 'console' is perfectly okay for a Node.js CLI tool and avoiding 8 | // it only brings unnecessary complexity 9 | 'no-console': 'off', 10 | 11 | // This is to allow a convention for exporting functions solely for 12 | // the purpose of the unit tests, see 13 | // https://github.com/apiaryio/dredd-transactions/pull/179#discussion_r206852270 14 | 'no-underscore-dangle': 'off', 15 | 16 | // Following rules were introduced to make the decaffeination 17 | // of the codebase possible and are to be removed in the future 18 | 'class-methods-use-this': 'off', 19 | 'consistent-return': 'off', 20 | 'import/no-extraneous-dependencies': 'off', 21 | 'import/no-unresolved': 'off', 22 | 'import/prefer-default-export': 'off', 23 | 'max-len': 'off', 24 | 'no-continue': 'off', 25 | 'no-empty': 'off', 26 | 'no-multi-assign': 'off', 27 | 'no-new': 'off', 28 | 'no-param-reassign': 'off', 29 | 'no-plusplus': 'off', 30 | 'no-restricted-syntax': 'off', 31 | 'no-use-before-define': 'off', 32 | 'prefer-destructuring': 'off', 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /packages/dredd/bin/dredd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Ignore this block, it's pure magic, temporary fix 4 | // for https://github.com/nodejs/node/issues/6456 5 | [process.stdout, process.stderr].forEach((s) => { 6 | if (s && s.isTTY && s._handle && s._handle.setBlocking) { 7 | s._handle.setBlocking(true); 8 | } 9 | }); 10 | 11 | const CLI = require('../build/CLI').default; 12 | 13 | const dreddCli = new CLI({ 14 | custom: { 15 | cwd: process.cwd(), 16 | argv: process.argv.slice(2), 17 | }, 18 | }); 19 | 20 | dreddCli.run(); 21 | -------------------------------------------------------------------------------- /packages/dredd/features/hooks-js.feature: -------------------------------------------------------------------------------- 1 | Feature: Hooks in JavaScript 2 | As a Dredd user 3 | In order to supplement or alter Dredd's default behavior 4 | I want to be able to run arbitrary code in JavaScript before and after HTTP transactions 5 | 6 | Background: 7 | Given I have an API description with transactions "GET /articles" and "POST /articles" 8 | And I have an implementation, which requires auth on "POST /articles" 9 | 10 | Scenario: Testing without hooks fails 11 | When I run Dredd 12 | Then the "GET /articles" test passes 13 | And the "POST /articles" test fails 14 | 15 | Scenario: Testing with hooks passes 16 | Given I have hooks adding auth to "POST /articles" 17 | When I run Dredd 18 | Then the "GET /articles" test passes 19 | And the "POST /articles" test passes 20 | -------------------------------------------------------------------------------- /packages/dredd/features/step_definitions/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | // prevents warnings in step definitions, where it makes no sense to give 4 | // a name to every function and where we need the function expression 5 | // to have access to 'this' 6 | 'func-names': 'off', 7 | 8 | // prevents warnings in assertions using 'expect()' 9 | 'no-unused-expressions': 'off', 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /packages/dredd/features/step_definitions/hooks-js.js: -------------------------------------------------------------------------------- 1 | const { spawn } = require('child_process'); 2 | const { expect } = require('chai'); 3 | const { Given, When, Then } = require('cucumber'); 4 | 5 | 6 | Given('I have an API description with transactions "GET /articles" and "POST /articles"', function () { 7 | this.dredd.apiDescription = `test/fixtures/blog/apidesc${this.apiDescriptionExt}`; 8 | }); 9 | 10 | Given('I have an implementation, which requires auth on "POST /articles"', function () { 11 | this.dredd.args.push('--server=node test/fixtures/blog/app.js'); 12 | }); 13 | 14 | Given('I have hooks adding auth to "POST /articles"', function () { 15 | this.dredd.args.push(`--hookfiles=test/fixtures/blog/hooks${this.hooksExt}`); 16 | }); 17 | 18 | When('I run Dredd', { timeout: 10 * 1000 }, function (callback) { 19 | const args = [ 20 | 'bin/dredd', 21 | this.dredd.apiDescription, 22 | this.dredd.apiLocation, 23 | '--no-color', 24 | ].concat(this.dredd.args); 25 | 26 | const cli = spawn('node', args); 27 | cli.stdout.on('data', (data) => { this.dredd.output += data; }); 28 | cli.stderr.on('data', (data) => { this.dredd.output += data; }); 29 | cli.on('exit', (exitStatus) => { this.dredd.exitStatus = exitStatus; callback(); }); 30 | }); 31 | 32 | Then('the "GET /articles" test passes', function () { 33 | expect(this.dredd.output).to.contain('pass: GET (200) /articles'); 34 | }); 35 | 36 | Then('the "POST /articles" test passes', function () { 37 | expect(this.dredd.output).to.contain('pass: POST (201) /articles'); 38 | }); 39 | 40 | Then('the "POST /articles" test fails', function () { 41 | expect(this.dredd.output).to.contain('fail: POST (201) /articles'); 42 | }); 43 | -------------------------------------------------------------------------------- /packages/dredd/features/support/world.js: -------------------------------------------------------------------------------- 1 | const { setWorldConstructor } = require('cucumber'); 2 | 3 | 4 | const API_DESCRIPTION_EXTS = { 5 | 'text/vnd.apiblueprint': '.apib', 6 | 'application/swagger+yaml': '.openapi2.yaml', 7 | 'application/vnd.oai.openapi': '.openapi3.yaml', 8 | }; 9 | 10 | const HOOKS_EXTS = { 11 | 'text/vnd.apiblueprint': '.apib.js', 12 | 'application/swagger+yaml': '.openapi2.js', 13 | 'application/vnd.oai.openapi': '.openapi3.js', 14 | }; 15 | 16 | 17 | function DreddWorld({ attach, parameters }) { 18 | this.attach = attach; 19 | this.parameters = parameters; 20 | 21 | this.apiDescriptionFormat = parameters.apiDescriptionFormat || 'text/vnd.apiblueprint'; 22 | this.apiDescriptionExt = API_DESCRIPTION_EXTS[this.apiDescriptionFormat]; 23 | this.hooksExt = HOOKS_EXTS[this.apiDescriptionFormat]; 24 | 25 | this.dredd = { 26 | apiDescription: null, 27 | apiLocation: 'http://127.0.0.1:3000', 28 | args: [], 29 | output: '', 30 | exitStatus: null, 31 | }; 32 | } 33 | 34 | 35 | setWorldConstructor(DreddWorld); 36 | -------------------------------------------------------------------------------- /packages/dredd/lib/compileTransactionName.js: -------------------------------------------------------------------------------- 1 | // This file is copy-pasted "as is" from the Dredd Transactions library, where 2 | // it's also tested. This is a temporary solution, 3 | // see https://github.com/apiaryio/dredd-transactions/issues/276 4 | export default function compileTransactionName(origin) { 5 | const segments = []; 6 | if (origin.apiName) { 7 | segments.push(origin.apiName); 8 | } 9 | if (origin.resourceGroupName) { 10 | segments.push(origin.resourceGroupName); 11 | } 12 | if (origin.resourceName) { 13 | segments.push(origin.resourceName); 14 | } 15 | if (origin.actionName) { 16 | segments.push(origin.actionName); 17 | } 18 | if (origin.exampleName) { 19 | segments.push(origin.exampleName); 20 | } 21 | return segments.join(' > '); 22 | } 23 | -------------------------------------------------------------------------------- /packages/dredd/lib/configUtils.js: -------------------------------------------------------------------------------- 1 | import clone from 'clone'; 2 | import fs from 'fs'; 3 | import yaml from 'js-yaml'; 4 | 5 | export function save(argsOrigin, path) { 6 | if (!path) { 7 | path = './dredd.yml'; 8 | } 9 | 10 | const args = clone(argsOrigin); 11 | 12 | args.blueprint = args._[0]; 13 | args.endpoint = args._[1]; 14 | 15 | Object.keys(args).forEach((key) => { 16 | if (key.length === 1) { 17 | delete args[key]; 18 | } 19 | }); 20 | 21 | delete args.$0; 22 | delete args._; 23 | 24 | fs.writeFileSync(path, yaml.dump(args)); 25 | } 26 | 27 | export function load(path) { 28 | if (!path) { 29 | path = './dredd.yml'; 30 | } 31 | 32 | const yamlData = fs.readFileSync(path); 33 | const data = yaml.safeLoad(yamlData); 34 | 35 | data._ = [data.blueprint, data.endpoint]; 36 | 37 | delete data.blueprint; 38 | delete data.endpoint; 39 | 40 | return data; 41 | } 42 | 43 | export function parseCustom(customArray) { 44 | const output = {}; 45 | if (Array.isArray(customArray)) { 46 | for (const string of customArray) { 47 | const splitted = string.split(/:(.+)?/); 48 | output[splitted[0]] = splitted[1]; 49 | } 50 | } 51 | return output; 52 | } 53 | -------------------------------------------------------------------------------- /packages/dredd/lib/configuration/applyLoggingOptions.js: -------------------------------------------------------------------------------- 1 | import logger from '../logger'; 2 | import reporterOutputLogger from '../reporters/reporterOutputLogger'; 3 | 4 | /** 5 | * Applies logging options from the given configuration. 6 | * Operates on the validated normalized config. 7 | */ 8 | function applyLoggingOptions(config) { 9 | if (config.color === false) { 10 | logger.transports.console.colorize = false; 11 | reporterOutputLogger.transports.console.colorize = false; 12 | } 13 | 14 | // TODO https://github.com/apiaryio/dredd/issues/1346 15 | if (config.loglevel) { 16 | const loglevel = config.loglevel.toLowerCase(); 17 | if (loglevel === 'silent') { 18 | logger.transports.console.silent = true; 19 | } else if (loglevel === 'warning') { 20 | logger.transports.console.level = 'warn'; 21 | } else if (loglevel === 'debug') { 22 | logger.transports.console.level = 'debug'; 23 | logger.transports.console.timestamp = true; 24 | } else if (['warn', 'error'].includes(loglevel)) { 25 | logger.transports.console.level = loglevel; 26 | } else { 27 | logger.transports.console.level = 'warn'; 28 | throw new Error( 29 | `The logging level '${loglevel}' is unsupported, ` + 30 | 'supported are: silent, error, warning, debug', 31 | ); 32 | } 33 | } else { 34 | logger.transports.console.level = 'warn'; 35 | } 36 | } 37 | 38 | export default applyLoggingOptions; 39 | -------------------------------------------------------------------------------- /packages/dredd/lib/configuration/index.js: -------------------------------------------------------------------------------- 1 | export { default as applyConfiguration } from './applyConfiguration'; 2 | export { default as applyLoggingOptions } from './applyLoggingOptions'; 3 | -------------------------------------------------------------------------------- /packages/dredd/lib/configuration/validateConfig.js: -------------------------------------------------------------------------------- 1 | const deprecatedOptions = [ 2 | { 3 | options: ['c'], 4 | message: 5 | 'DEPRECATED: The -c configuration option is deprecated. Plese use --color instead.', 6 | }, 7 | { 8 | options: ['data'], 9 | message: 10 | 'DEPRECATED: The --data configuration option is deprecated ' + 11 | 'in favor of `apiDescriptions`, please see https://dredd.org', 12 | }, 13 | { 14 | options: ['blueprintPath'], 15 | message: 16 | 'DEPRECATED: The --blueprintPath configuration option is deprecated, ' + 17 | 'please use --path instead.', 18 | }, 19 | { 20 | options: ['level'], 21 | message: 22 | 'DEPRECATED: The --level configuration option is deprecated. Please use --loglevel instead.', 23 | }, 24 | ]; 25 | 26 | const unsupportedOptions = [ 27 | { 28 | options: ['timestamp', 't'], 29 | message: 30 | 'REMOVED: The --timestamp/-t configuration option is no longer supported. Please use --loglevel=debug instead.', 31 | }, 32 | { 33 | options: ['silent', 'q'], 34 | message: 35 | 'REMOVED: The --silent/-q configuration option is no longer supported. Please use --loglevel=silent instead.', 36 | }, 37 | { 38 | options: ['sandbox', 'b'], 39 | message: 40 | 'REMOVED: Dredd does not support sandboxed JS hooks anymore, use standard JS hooks instead.', 41 | }, 42 | { 43 | options: ['hooksData'], 44 | message: 45 | 'REMOVED: Dredd does not support sandboxed JS hooks anymore, use standard JS hooks instead.', 46 | }, 47 | ]; 48 | 49 | function flushMessages(rules, config) { 50 | return Object.keys(config).reduce((messages, configKey) => { 51 | const warning = rules.find((rule) => rule.options.includes(configKey)); 52 | return warning ? messages.concat(warning.message) : messages; 53 | }, []); 54 | } 55 | 56 | /** 57 | * Returns the errors and warnings relative to the given config. 58 | */ 59 | const validateConfig = (config) => ({ 60 | warnings: flushMessages(deprecatedOptions, config), 61 | errors: flushMessages(unsupportedOptions, config), 62 | }); 63 | 64 | export default validateConfig; 65 | -------------------------------------------------------------------------------- /packages/dredd/lib/general.ts: -------------------------------------------------------------------------------- 1 | export enum HTTPMethod { 2 | CONNECT = 'CONNECT', 3 | OPTIONS = 'OPTIONS', 4 | POST = 'POST', 5 | GET = 'GET', 6 | HEAD = 'HEAD', 7 | PUT = 'PUT', 8 | PATCH = 'PATCH', 9 | LINK = 'LINK', 10 | UNLINK = 'UNLINK', 11 | DELETE = 'DELETE', 12 | TRACE = 'TRACE' 13 | } 14 | 15 | export enum BodyEncoding { 16 | 'utf-8', 17 | 'base64', 18 | } 19 | 20 | export enum TransactionTestStatus { 21 | 'pass', 22 | 'fail', 23 | 'skip', 24 | } 25 | 26 | export interface Transaction { 27 | id: string; 28 | name: string; 29 | origin: TransactionOrigin; 30 | host: string; 31 | port: number; 32 | protocol: 'http:' | 'https:'; 33 | fullPath: string; 34 | request: TransactionRequest; 35 | expected: { 36 | statusCode: number; 37 | headers: Record; 38 | body: string; 39 | bodySchema: Record; 40 | }; 41 | real: { 42 | statusCode: string; 43 | headers: Record; 44 | body: string; 45 | bodyEncoding: BodyEncoding; 46 | }; 47 | skip: boolean; 48 | fail: boolean; 49 | 50 | test: TransactionTest; 51 | } 52 | 53 | export interface TransactionRequest { 54 | method: HTTPMethod; 55 | url: string; 56 | body?: string; 57 | bodyEncoding?: BodyEncoding; 58 | headers?: Record; 59 | } 60 | 61 | export interface TransactionOrigin { 62 | filename: string; 63 | apiName: string; 64 | resourceGroupName: string; 65 | resourceName: string; 66 | actionName: string; 67 | exampleName: string; 68 | } 69 | 70 | export interface TransactionTest { 71 | start: Date; 72 | end: Date; 73 | duration: number; 74 | startedAt: number; 75 | title: string; 76 | request: TransactionRequest; 77 | actual: any; 78 | expected: any; 79 | status: TransactionTestStatus; 80 | message: string; 81 | results: any; 82 | valid: boolean; 83 | origin: TransactionOrigin; 84 | } 85 | -------------------------------------------------------------------------------- /packages/dredd/lib/getGoBinary.js: -------------------------------------------------------------------------------- 1 | import childProcess from 'child_process'; 2 | import path from 'path'; 3 | 4 | // Docs: 5 | // - https://golang.org/doc/code.html#GOPATH 6 | // - https://golang.org/cmd/go/#hdr-GOPATH_environment_variable 7 | export default function getGoBinary(callback) { 8 | const goBin = process.env.GOBIN; 9 | if (goBin) { 10 | process.nextTick(() => callback(null, goBin)); 11 | } else if (process.env.GOPATH) { 12 | process.nextTick(() => 13 | callback(null, path.join(process.env.GOPATH, 'bin')), 14 | ); 15 | } else { 16 | childProcess.exec('go env GOPATH', (err, stdout) => { 17 | if (err) { 18 | return callback(err); 19 | } 20 | callback(null, path.join(stdout.trim(), 'bin')); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/dredd/lib/getProxySettings.js: -------------------------------------------------------------------------------- 1 | const PROXY_ENV_VARIABLES = ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY']; 2 | 3 | /** 4 | * Expects an environment variables object (typically process.env) 5 | * and returns an array of strings representing HTTP proxy settings, 6 | * such as ['HTTPS_PROXY=https://proxy.example.com:8080', ...] 7 | * 8 | * Supports both upper and lower case names and skips env vars set as empty 9 | * strings (other falsy values are not taken care of as env vars can only 10 | * be strings). 11 | * 12 | * Note: The settings are later only printed to the user. Applying the settings 13 | * is handled directly by the 'request' library, see 14 | * https://github.com/request/request#user-content-proxies 15 | */ 16 | export default function getProxySettings(env) { 17 | return Object.entries(env) 18 | .filter((entry) => PROXY_ENV_VARIABLES.includes(entry[0].toUpperCase())) 19 | .filter((entry) => entry[1] !== '') 20 | .map((entry) => `${entry[0]}=${entry[1]}`); 21 | } 22 | -------------------------------------------------------------------------------- /packages/dredd/lib/hooksLog.js: -------------------------------------------------------------------------------- 1 | import util from 'util'; 2 | 3 | export default function hooksLog(logs = [], logger, content) { 4 | // Log to logger 5 | if (logger && typeof logger.hook === 'function') { 6 | logger.hook(content); 7 | } 8 | 9 | // Append to array of logs to allow further operations, e.g. send all hooks logs to Apiary 10 | logs.push({ 11 | timestamp: Date.now(), 12 | content: typeof content === 'object' ? util.format(content) : `${content}`, 13 | }); 14 | 15 | return logs; 16 | } 17 | -------------------------------------------------------------------------------- /packages/dredd/lib/ignorePipeErrors.js: -------------------------------------------------------------------------------- 1 | // On Windows, killing stdin / stdout / stderr pipes intentionally 2 | // on either side can result `uncaughtException` causing 3 | // dredd main process exiting with exitCode 7 instead of 1. This _fix_ 4 | // remedies the issue. 5 | export default function ignorePipeErrors(proc) { 6 | if (proc.stdout) proc.stdout.on('error', () => {}); 7 | if (proc.stderr) proc.stderr.on('error', () => {}); 8 | if (proc.stdin) proc.stdin.on('error', () => {}); 9 | } 10 | -------------------------------------------------------------------------------- /packages/dredd/lib/index.js: -------------------------------------------------------------------------------- 1 | // This is an explicit package entry for proper exports. 2 | // When exported via "export default", the Dredd package 3 | // would need to be required as: 4 | // 5 | // const Dredd = require('dredd').default 6 | // 7 | // To prevent this, using "module.exports". 8 | import Dredd from './Dredd'; 9 | 10 | module.exports = Dredd; 11 | -------------------------------------------------------------------------------- /packages/dredd/lib/isURL.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Decides whether given string is a URL or not 3 | */ 4 | export default function isURL(location: string): boolean { 5 | return /^http(s)?:\/\//.test(location); 6 | } 7 | -------------------------------------------------------------------------------- /packages/dredd/lib/logger.js: -------------------------------------------------------------------------------- 1 | import winston from 'winston'; 2 | 3 | const logger = new winston.Logger({ 4 | transports: [new winston.transports.Console({ colorize: true })], 5 | levels: { 6 | debug: 2, 7 | warn: 1, 8 | error: 0, 9 | }, 10 | colors: { 11 | debug: 'cyan', 12 | warn: 'yellow', 13 | error: 'red', 14 | }, 15 | }); 16 | 17 | export default logger; 18 | -------------------------------------------------------------------------------- /packages/dredd/lib/prettifyResponse.js: -------------------------------------------------------------------------------- 1 | import html from 'html'; 2 | 3 | import logger from './logger'; 4 | 5 | export default function prettifyResponse(response) { 6 | let contentType; 7 | 8 | function stringify(obj) { 9 | try { 10 | if (typeof obj === 'string') { 11 | obj = JSON.parse(obj); 12 | } 13 | obj = JSON.stringify(obj, null, 2); 14 | } catch (e) { 15 | logger.debug(`Could not stringify: ${obj}`); 16 | } 17 | return obj; 18 | } 19 | 20 | function prettifyBody(body, contentKind) { 21 | switch (contentKind) { 22 | case 'text/html': 23 | body = html.prettyPrint(body, { indent_size: 2 }); 24 | break; 25 | default: 26 | body = stringify(body); 27 | } 28 | return body; 29 | } 30 | 31 | if (response && response.headers) { 32 | contentType = 33 | response.headers['content-type'] || response.headers['Content-Type']; 34 | } 35 | 36 | let stringRepresentation = ''; 37 | for (const key of Object.keys(response || {})) { 38 | let value = response[key]; 39 | if (key === 'body') { 40 | value = `\n${prettifyBody(value, contentType)}`; 41 | } else if (key === 'schema') { 42 | value = `\n${stringify(value)}`; 43 | } else if (key === 'headers') { 44 | let header = '\n'; 45 | for (const hkey of Object.keys(value || {})) { 46 | const hval = value[hkey]; 47 | header += ` ${hkey}: ${hval}\n`; 48 | } 49 | value = header; 50 | } 51 | 52 | stringRepresentation += `${key}: ${value}\n`; 53 | } 54 | 55 | return stringRepresentation; 56 | } 57 | -------------------------------------------------------------------------------- /packages/dredd/lib/reporters/BaseReporter.js: -------------------------------------------------------------------------------- 1 | import logger from '../logger'; 2 | 3 | function BaseReporter(emitter, stats) { 4 | this.type = 'base'; 5 | this.stats = stats; 6 | this.configureEmitter(emitter); 7 | logger.debug(`Using '${this.type}' reporter.`); 8 | } 9 | 10 | BaseReporter.prototype.configureEmitter = function configureEmitter(emitter) { 11 | emitter.on('start', (apiDescriptions, callback) => { 12 | this.stats.start = new Date(); 13 | callback(); 14 | }); 15 | 16 | emitter.on('end', (callback) => { 17 | this.stats.end = new Date(); 18 | this.stats.duration = this.stats.end - this.stats.start; 19 | callback(); 20 | }); 21 | 22 | emitter.on('test start', (test) => { 23 | this.stats.tests += 1; 24 | test.start = new Date(); 25 | }); 26 | 27 | emitter.on('test pass', (test) => { 28 | this.stats.passes += 1; 29 | test.end = new Date(); 30 | if (typeof test.start === 'string') { 31 | test.start = new Date(test.start); 32 | } 33 | test.duration = test.end - test.start; 34 | }); 35 | 36 | emitter.on('test skip', () => { 37 | this.stats.skipped += 1; 38 | }); 39 | 40 | emitter.on('test fail', (test) => { 41 | this.stats.failures += 1; 42 | test.end = new Date(); 43 | if (typeof test.start === 'string') { 44 | test.start = new Date(test.start); 45 | } 46 | test.duration = test.end - test.start; 47 | }); 48 | 49 | emitter.on('test error', (error, test) => { 50 | this.stats.errors += 1; 51 | test.end = new Date(); 52 | if (typeof test.start === 'string') { 53 | test.start = new Date(test.start); 54 | } 55 | test.duration = test.end - test.start; 56 | }); 57 | }; 58 | 59 | export default BaseReporter; 60 | -------------------------------------------------------------------------------- /packages/dredd/lib/reporters/reporterOutputLogger.js: -------------------------------------------------------------------------------- 1 | import winston from 'winston'; 2 | 3 | const logger = new winston.Logger({ 4 | transports: [ 5 | new winston.transports.Console({ colorize: true, level: 'info' }), 6 | ], 7 | levels: { 8 | info: 10, 9 | test: 9, 10 | pass: 8, 11 | fail: 7, 12 | complete: 6, 13 | actual: 5, 14 | expected: 4, 15 | hook: 3, 16 | request: 2, 17 | skip: 1, 18 | error: 0, 19 | }, 20 | colors: { 21 | info: 'blue', 22 | test: 'yellow', 23 | pass: 'green', 24 | fail: 'red', 25 | complete: 'green', 26 | actual: 'red', 27 | expected: 'red', 28 | hook: 'green', 29 | request: 'green', 30 | skip: 'yellow', 31 | error: 'red', 32 | }, 33 | }); 34 | 35 | export default logger; 36 | -------------------------------------------------------------------------------- /packages/dredd/lib/resolveLocations.ts: -------------------------------------------------------------------------------- 1 | import resolvePaths from './resolvePaths'; 2 | import isURL from './isURL'; 3 | 4 | /** 5 | * Takes an array of strings representing API description document locations 6 | * and resolves all relative paths and globs 7 | * 8 | * Keeps URLs intact. Keeps the original order. Throws in case there's a glob 9 | * pattern which doesn't resolve to any existing files. 10 | */ 11 | export default function resolveLocations( 12 | workingDirectory: string, 13 | locations: string[], 14 | ): string[] { 15 | const resolvedLocations = locations 16 | // resolves paths to local files, produces an array of arrays 17 | .map((location) => 18 | isURL(location) ? [location] : resolvePaths(workingDirectory, [location]), 19 | ) 20 | // flattens the array of arrays 21 | .reduce((flatArray, array) => flatArray.concat(array), []); 22 | 23 | return Array.from(new Set(resolvedLocations)); 24 | } 25 | -------------------------------------------------------------------------------- /packages/dredd/lib/resolveModule.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export default function resolveModule( 5 | workingDirectory: string, 6 | moduleName: string, 7 | ): string { 8 | const absolutePath = path.resolve(workingDirectory, moduleName); 9 | return fs.existsSync(absolutePath) || fs.existsSync(`${absolutePath}.js`) 10 | ? absolutePath 11 | : moduleName; 12 | } 13 | -------------------------------------------------------------------------------- /packages/dredd/lib/resolvePaths.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import glob from 'glob'; 4 | 5 | // Ensure platform-agnostic 'path.basename' function 6 | const basename = 7 | process.platform === 'win32' ? path.win32.basename : path.basename; 8 | 9 | function resolveGlob(workingDirectory: string, pattern: string): string[] { 10 | // 'glob.sync()' does not resolve paths, only glob patterns 11 | if (glob.hasMagic(pattern)) { 12 | return glob 13 | .sync(pattern, { cwd: workingDirectory }) 14 | .map((matchingPath) => path.resolve(workingDirectory, matchingPath)); 15 | } 16 | const resolvedPath = path.resolve(workingDirectory, pattern); 17 | return fs.existsSync(resolvedPath) ? [resolvedPath] : []; 18 | } 19 | 20 | /** 21 | * Resolve paths to files 22 | * 23 | * Resolves glob patterns and sorts the files alphabetically by their basename. 24 | * Throws in case there's a pattern which doesn't resolve to any existing files. 25 | */ 26 | export default function resolvePaths( 27 | workingDirectory: string, 28 | patterns: string[], 29 | ) { 30 | if (!patterns || patterns.length < 1) { 31 | return []; 32 | } 33 | 34 | const resolvedPaths = patterns 35 | .map((pattern) => { 36 | const paths = resolveGlob(workingDirectory, pattern); 37 | if (paths.length < 1) { 38 | throw new Error(`Could not find any files on path: '${pattern}'`); 39 | } 40 | return paths; 41 | }) 42 | .reduce((flatPaths, paths) => flatPaths.concat(paths), []) 43 | .sort((p1, p2) => { 44 | const [basename1, basename2] = [basename(p1), basename(p2)]; 45 | if (basename1 < basename2) return -1; 46 | if (basename1 > basename2) return 1; 47 | return 0; 48 | }); 49 | 50 | return Array.from(new Set(resolvedPaths)); // keep only unique items 51 | } 52 | -------------------------------------------------------------------------------- /packages/dredd/lib/sortTransactions.ts: -------------------------------------------------------------------------------- 1 | import { HTTPMethod, Transaction } from './general'; 2 | 3 | const sortedMethods: HTTPMethod[] = [ 4 | HTTPMethod.CONNECT, 5 | HTTPMethod.OPTIONS, 6 | HTTPMethod.POST, 7 | HTTPMethod.GET, 8 | HTTPMethod.HEAD, 9 | HTTPMethod.PUT, 10 | HTTPMethod.PATCH, 11 | HTTPMethod.LINK, 12 | HTTPMethod.UNLINK, 13 | HTTPMethod.DELETE, 14 | HTTPMethod.TRACE, 15 | ]; 16 | 17 | // Often, API description is arranged with a sequence of methods that lends 18 | // itself to understanding by the human reading the documentation. 19 | // 20 | // However, the sequence of methods may not be appropriate for the machine 21 | // reading the documentation in order to test the API. 22 | // 23 | // By sorting the transactions by their methods, it is possible to ensure that 24 | // objects are created before they are read, updated, or deleted. 25 | export default function sortTransactions( 26 | transactions: Transaction[], 27 | ): Transaction[] { 28 | // Convert the list of transactions into a list of tuples 29 | // that hold each trasnaction index and details. 30 | const tempTransactions: Array<[number, Transaction]> = transactions.map( 31 | (transaction, index) => [index, transaction], 32 | ); 33 | 34 | tempTransactions.sort( 35 | ([leftIndex, leftTransaction], [rightIndex, rightTransaction]) => { 36 | const methodIndexA = sortedMethods.indexOf( 37 | leftTransaction.request.method, 38 | ); 39 | const methodIndexB = sortedMethods.indexOf( 40 | rightTransaction.request.method, 41 | ); 42 | 43 | // Sort transactions according to the transaction's request method 44 | if (methodIndexA < methodIndexB) { 45 | return -1; 46 | } 47 | 48 | if (methodIndexA > methodIndexB) { 49 | return 1; 50 | } 51 | 52 | // In case two transactions' request methods are the same, 53 | // preserve the original order of those transactions 54 | return leftIndex - rightIndex; 55 | }, 56 | ); 57 | 58 | const cleanTransactions = tempTransactions.map( 59 | ([_, transaction]) => transaction, 60 | ); 61 | 62 | return cleanTransactions; 63 | } 64 | -------------------------------------------------------------------------------- /packages/dredd/lib/which.js: -------------------------------------------------------------------------------- 1 | import which from 'which'; 2 | 3 | export default { 4 | which(command) { 5 | try { 6 | which.sync(command); 7 | return true; 8 | } catch (e) { 9 | return false; 10 | } 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/dredd/readthedocs.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: latest 3 | python: 4 | version: 3.6 5 | -------------------------------------------------------------------------------- /packages/dredd/scripts/smoke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Performs a smoke test verifying the package produced by the build 3 | # is installable and that Dredd's core life functions are okay 4 | 5 | # Aborts as soon as anything returns non-zero exit status 6 | set -e 7 | 8 | TMPDIR="$(mktemp -d)" 9 | PROJECT_DIR="$(pwd)/../.." 10 | 11 | # install monorepo package into $TMPDIR 12 | install() { 13 | PACKAGE="$1" 14 | 15 | cd "$PROJECT_DIR/packages/$PACKAGE" 16 | TARBALL="$(npm pack | tail -n1)" 17 | mv "$PROJECT_DIR/packages/$PACKAGE/$TARBALL" "$TMPDIR" 18 | 19 | cd "$TMPDIR" && npm install --no-save "$TARBALL" 20 | } 21 | 22 | git clone https://github.com/apiaryio/dredd-example.git "$TMPDIR" 23 | install dredd-transactions 24 | install dredd 25 | 26 | cd "$TMPDIR" 27 | 28 | # Install dredd-example's dependencies 29 | npm install 30 | 31 | # Assert that Protagonist (the C++ dependency) was not installed 32 | if [[ "$(find node_modules -name protagonist)" != "" ]]; then 33 | echo "ERROR: It looks like Dredd has tried to install the 'protagonist'"\ 34 | "library (a C++ binding for the API Blueprint parser), which is"\ 35 | "an unwanted behavior of the installation process. The lock file"\ 36 | "of the 'dredd-transactions' library together with its"\ 37 | "'scripts/postshrinkwrap.js' script should have prevented this." 38 | exit 1 39 | fi 40 | 41 | # Test the 'dredd-example' project 42 | npm test 43 | 44 | # Test the JavaScript API 45 | node -e 'process.exitCode = (new (require("dredd"))({})).run ? 0 : 1;' 46 | 47 | rm -fr "$TMPDIR" 48 | -------------------------------------------------------------------------------- /packages/dredd/test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | mocha: true, 4 | node: true, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/531-produces-consumes.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: "Blog API" 4 | version: "1.0" 5 | consumes: 6 | - "application/hal+json; charset=utf-8" 7 | produces: 8 | - "application/hal+json; charset=utf-8" 9 | paths: 10 | "/articles": 11 | x-summary: "Articles" 12 | get: 13 | summary: "List articles" 14 | description: "Retrieve a list of all articles" 15 | responses: 16 | 200: 17 | description: "Articles list" 18 | examples: 19 | "application/hal+json; charset=utf-8": 20 | - id: 1 21 | title: "Creamy cucumber salad" 22 | text: "Slice cucumbers…" 23 | _links: { 24 | self: { 25 | href: "/articles/1" 26 | } 27 | } 28 | post: 29 | summary: "Publish an article" 30 | description: "Create and publish a new article" 31 | parameters: 32 | - name: "body" 33 | in: "body" 34 | schema: 35 | example: 36 | title: "Crispy schnitzel" 37 | text: "Prepare eggs…" 38 | responses: 39 | 201: 40 | description: "New article" 41 | examples: 42 | "application/hal+json; charset=utf-8": 43 | id: 2 44 | title: "Crispy schnitzel" 45 | text: "Prepare eggs…" 46 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/apiary.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines collection [/machines] 8 | 9 | ## Create a Machine [POST] 10 | + Request (application/json) 11 | 12 | { 13 | "type": "bulldozer", 14 | "name": "willy" 15 | } 16 | 17 | + Response 202 (application/json) 18 | 19 | { 20 | "mesage": "Accepted" 21 | } 22 | 23 | 24 | ## Retreive all Machines [GET] 25 | 26 | + Response 200 (application/json) 27 | 28 | [{ 29 | "_id": "52341870ed55224b15ff07ef", 30 | "type": "bulldozer", 31 | "name": "willy" 32 | }] 33 | 34 | # Machine [/machines/{name}] 35 | + Parameters 36 | + name (required,`willy`) 37 | 38 | ## Update a Machine [PUT] 39 | 40 | + Request (application/json) 41 | 42 | { 43 | "name": "waldo" 44 | } 45 | 46 | + Response 200 (application/json) 47 | 48 | { 49 | "type": "bulldozer", 50 | "name": "waldo", 51 | "_id": "5229c6e8e4b0bd7dbb07e29c" 52 | } 53 | 54 | ## Retrieve a Machine [GET] 55 | + Parameters 56 | + name (required,`waldo`) 57 | 58 | + Response 200 (text/plain) 59 | 60 | { 61 | "type": "bulldozer", 62 | "name": "waldo", 63 | "_id": "5229c6e8e4b0bd7dbb07e29c" 64 | } 65 | 66 | ## Delete Message [DELETE] 67 | + Parameters 68 | + name (required,`waldo`) 69 | + Response 204 70 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/arbitrary-action.md: -------------------------------------------------------------------------------- 1 | # My API 2 | 3 | # My Group 4 | 5 | # My Resource [/resource/{id}] 6 | + Parameters 7 | + id: 1 (number) ... Unique identifier of the respource 8 | 9 | # My normal action [POST] 10 | 11 | + Response 200 (text/plain) 12 | 13 | Woof 14 | 15 | # My Arbitrary action [GET /resource-cool-url/{otherparam}] 16 | 17 | + Parameters 18 | + otherparam: othervalue (string) ... Parameter not present under resource 19 | 20 | + Response 200 (text/plain) 21 | 22 | Booboo 23 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/blog/apidesc.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Blog API 4 | ## Articles [/articles] 5 | ### List articles [GET] 6 | 7 | + Response 200 (application/json; charset=utf-8) 8 | 9 | [ 10 | { 11 | "id": 1, 12 | "title": "Creamy cucumber salad", 13 | "text": "Slice cucumbers…" 14 | } 15 | ] 16 | 17 | ### Publish an article [POST] 18 | 19 | + Request (application/json; charset=utf-8) 20 | 21 | { 22 | "title": "Crispy schnitzel", 23 | "text": "Prepare eggs…" 24 | } 25 | 26 | + Response 201 (application/json; charset=utf-8) 27 | 28 | { 29 | "id": 2, 30 | "title": "Crispy schnitzel", 31 | "text": "Prepare eggs…" 32 | } 33 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/blog/apidesc.openapi2.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: "Blog API" 4 | version: "1.0" 5 | consumes: 6 | - "application/json; charset=utf-8" 7 | produces: 8 | - "application/json; charset=utf-8" 9 | paths: 10 | "/articles": 11 | x-summary: "Articles" 12 | get: 13 | summary: "List articles" 14 | description: "Retrieve a list of all articles" 15 | responses: 16 | 200: 17 | description: "Articles list" 18 | examples: 19 | "application/json; charset=utf-8": 20 | - id: 1 21 | title: "Creamy cucumber salad" 22 | text: "Slice cucumbers…" 23 | post: 24 | summary: "Publish an article" 25 | description: "Create and publish a new article" 26 | parameters: 27 | - name: "body" 28 | in: "body" 29 | schema: 30 | example: 31 | title: "Crispy schnitzel" 32 | text: "Prepare eggs…" 33 | responses: 34 | 201: 35 | description: "New article" 36 | examples: 37 | "application/json; charset=utf-8": 38 | id: 2 39 | title: "Crispy schnitzel" 40 | text: "Prepare eggs…" 41 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/blog/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | 4 | const app = express(); 5 | 6 | app.get('/articles', (req, res) => { 7 | res.json([{ id: 1, title: 'Creamy cucumber salad', text: 'Slice cucumbers…' }]); 8 | }); 9 | 10 | app.post('/articles', (req, res) => { 11 | if (req.headers.authorization) { 12 | res.status(201).json({ id: 2, title: 'Crispy schnitzel', text: 'Prepare eggs…' }); 13 | } else { 14 | res.status(403).json({ error: 'Forbidden' }); 15 | } 16 | }); 17 | 18 | 19 | app.listen(3000, () => console.log('http://127.0.0.1:3000')); 20 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/blog/hooks.apib.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.before('Articles > Publish an article', (transaction) => { 4 | transaction.request.headers.Authorization = 'Basic: YWxhZGRpbjpvcGVuc2VzYW1l'; 5 | }); 6 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/blog/hooks.openapi2.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.before('Articles > Publish an article > 201 > application/json; charset=utf-8', (transaction) => { 4 | transaction.request.headers.Authorization = 'Basic: YWxhZGRpbjpvcGVuc2VzYW1l'; 5 | }); 6 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/error-blueprint.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/error-openapi2.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Machines API 4 | paths: 5 | '/machines': 6 | x-summary: Machines Collection 7 | get: 8 | summary: Get Machines 9 | responses: 10 | 200: 11 | schema: 12 | type: array 13 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/error-uri-template.apib: -------------------------------------------------------------------------------- 1 | FORMAT: X-1A 2 | 3 | # Machines API 4 | # Group Machines 5 | 6 | # Machine [/machines/{name] 7 | + Parameters 8 | + name (required,`willy`) 9 | 10 | ## Update a Machine [PUT] 11 | 12 | + Request (application/json) 13 | 14 | { 15 | "name": "waldo" 16 | } 17 | 18 | + Response 200 (application/json) 19 | 20 | { 21 | "type": "bulldozer", 22 | "name": "waldo", 23 | "_id": "5229c6e8e4b0bd7dbb07e29c" 24 | } 25 | 26 | ## Retrieve a Machine [GET] 27 | + Parameters 28 | + name (required,`waldo`) 29 | 30 | + Response 200 (text/plain) 31 | 32 | { 33 | "type": "bulldozer", 34 | "name": "waldo", 35 | "_id": "5229c6e8e4b0bd7dbb07e29c" 36 | } 37 | 38 | ## Delete Message [DELETE] 39 | + Parameters 40 | + name (required,`waldo`) 41 | + Response 204 42 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/groupless-names.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | const before = hooks.before; 4 | const after = hooks.after; 5 | 6 | after(' > Machines collection > Get Machines', (transaction) => { 7 | transaction.fail = 'failed in sandboxed hook'; 8 | }); 9 | 10 | before(' > Machines collection > Get Machines', (transaction) => { 11 | transaction.fail = 'failed in sandboxed hook'; 12 | }); 13 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/bar/b.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/bar/b.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/bar/p.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/bar/p.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/bar/z.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/bar/z.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/baz/c.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/baz/c.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/baz/x.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/baz/x.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/foo/a.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/foo/a.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/foo/o.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/foo/o.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-glob/foo/y.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks-glob/foo/y.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks-log.coffee: -------------------------------------------------------------------------------- 1 | {before, after, log} = require 'hooks' 2 | 3 | before "Machines > Machines collection > Get Machines", (transaction) -> 4 | log {err: 'Error object!'} 5 | log true 6 | 7 | after "Machines > Machines collection > Get Machines", (transaction) -> 8 | log "using hooks.log to debug" 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/hooks.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/hooks.js -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/https/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEJTCCA46gAwIBAgIJAOj5HvOn36y9MA0GCSqGSIb3DQEBBQUAMIG+MQswCQYD 3 | VQQGEwJDWjEVMBMGA1UECBMMTWlkZGxlLWVhcnRoMREwDwYDVQQHEwhUaW1idWt0 4 | dTEvMC0GA1UEChMmU3VwZXJjYWxpZnJhZ2lsaXN0aWNleHBpYWxpZG9jaW91cyBM 5 | dGQxHDAaBgNVBAsTE0p1ZGljaWFsIERlcGFydG1lbnQxETAPBgNVBAMTCEpvaG4g 6 | RG9lMSMwIQYJKoZIhvcNAQkBFhRqb2huLmRvZUBleGFtcGxlLmNvbTAeFw0xNzAz 7 | MjMxNjIxMzZaFw0xNzA0MjIxNjIxMzZaMIG+MQswCQYDVQQGEwJDWjEVMBMGA1UE 8 | CBMMTWlkZGxlLWVhcnRoMREwDwYDVQQHEwhUaW1idWt0dTEvMC0GA1UEChMmU3Vw 9 | ZXJjYWxpZnJhZ2lsaXN0aWNleHBpYWxpZG9jaW91cyBMdGQxHDAaBgNVBAsTE0p1 10 | ZGljaWFsIERlcGFydG1lbnQxETAPBgNVBAMTCEpvaG4gRG9lMSMwIQYJKoZIhvcN 11 | AQkBFhRqb2huLmRvZUBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw 12 | gYkCgYEAr4lesAOSSUzABgMgtNvZK3+ydrH5iGhWeUSazMU1NhlKVtmkNVXIhq/C 13 | v8q53/e2JKBM5p0a1quNHETeS7jEq2GS+ij/4OMEg8rHdtwp42vYO77Gt5sC2eGs 14 | 1b8T1IqrJystWvi4Nfeml7ePPcEkD7qJbjGwGF7Q4zF4rqIjHa8CAwEAAaOCAScw 15 | ggEjMB0GA1UdDgQWBBR5WzJXBUNUTKClS/eHQA1J0wHXizCB8wYDVR0jBIHrMIHo 16 | gBR5WzJXBUNUTKClS/eHQA1J0wHXi6GBxKSBwTCBvjELMAkGA1UEBhMCQ1oxFTAT 17 | BgNVBAgTDE1pZGRsZS1lYXJ0aDERMA8GA1UEBxMIVGltYnVrdHUxLzAtBgNVBAoT 18 | JlN1cGVyY2FsaWZyYWdpbGlzdGljZXhwaWFsaWRvY2lvdXMgTHRkMRwwGgYDVQQL 19 | ExNKdWRpY2lhbCBEZXBhcnRtZW50MREwDwYDVQQDEwhKb2huIERvZTEjMCEGCSqG 20 | SIb3DQEJARYUam9obi5kb2VAZXhhbXBsZS5jb22CCQDo+R7zp9+svTAMBgNVHRME 21 | BTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAIx5GAPEKhhHi/ycy0XE45+kmUld4SL9 22 | Cbmh41YEu0roITQPbp56AQCqY0mlnxfJEPavbPS32gKpauoVJtQSmnhVdey4b8TZ 23 | uggYrSCewk539yJTL1mP+M0Hjf5MtI8fEOBUftXkDuFACGPuZdabhV9MOTBjdoPo 24 | MANdCebwJuN8 25 | -----END CERTIFICATE----- 26 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/https/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQCviV6wA5JJTMAGAyC029krf7J2sfmIaFZ5RJrMxTU2GUpW2aQ1 3 | VciGr8K/yrnf97YkoEzmnRrWq40cRN5LuMSrYZL6KP/g4wSDysd23Cnja9g7vsa3 4 | mwLZ4azVvxPUiqsnKy1a+Lg196aXt489wSQPuoluMbAYXtDjMXiuoiMdrwIDAQAB 5 | AoGAZwlmeEEQbFBN4vmRCDiISH1Df2LGy2gbYkF/8DTOIDxGI6bLObdp5o1i7nuM 6 | EchwtR0XJsMPTvUR9ocCSUZiwhD/0Vsfsb6ualDpRzc8siOQdACYG/S2QEd+bdcj 7 | b5n2ZRHxglgeAtU1PrWLXbb8rx9KSN7/FhNKUpaF/kF0eXECQQDk/42tXOBY5qgu 8 | Bgnd4FQ3DJKr5xQk0lQU3B3kGuzg3RRQSR++/dxIRimoyKoUgORdSyB55XOUKVFI 9 | gmAhZDR3AkEAxDwLiZx87vluFI5sWCjm+TSRcv5TjZl0RD/SrvFhVCVFJHZOlHL/ 10 | tkHTUTIim8dB1KjPpjXKa+b09bBQW0nGiQJBAIa7cQEiFwFXXHYPqXh4xzPIWvd3 11 | MtvjQAMx6whNazd1+8Cs9VerBxMi7NnYjnEX0MSvMgFmJdVzZdaSlrquuUsCQQCc 12 | bc04trF1Aws4gcxmfryY/cnQpGLQpvpjCYmWgb73h/pVNaYwenfTvyeIO3IRQkb9 13 | ElDti0XAvEybqiB0lRwZAkB88wihgP6DMAxoUXL2ipqpVvqwsxG/gZmT1o/Ds87H 14 | ma4Y6Id85DO6b18ek7xj03PGWZYY/dqYLXOItnVCLLva 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/image.png -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/json-schema-draft-7-boolean.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines collection [/machines/{id}] 8 | + Parameters 9 | + id: 1 (number) 10 | 11 | ## Get Machines [GET] 12 | 13 | + Request (application/json) 14 | + Parameters 15 | + id: 2 (number) 16 | 17 | + Response 200 (application/json; charset=utf-8) 18 | 19 | + Schema 20 | 21 | true 22 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/json-schema-draft-7.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines collection [/machines] 8 | 9 | ## Get Machines [GET] 10 | 11 | - Response 200 (application/json; charset=utf-8) 12 | 13 | + Schema 14 | 15 | { 16 | "$schema": "http://json-schema.org/draft-07/schema#", 17 | "type": "array", 18 | "items": { 19 | "type": "object", 20 | "properties": { 21 | "type": { 22 | "type": "string", 23 | "const": "bulldozer" 24 | }, 25 | "name": { 26 | "not": { 27 | "type": "number" 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/multifile/greeting.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Greeting API 4 | 5 | ## GET /greeting 6 | + Response 200 (text/plain; charset=utf-8) 7 | 8 | Howdy! 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/multifile/message.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Message API 4 | 5 | ## GET /message 6 | + Response 200 (text/plain; charset=utf-8) 7 | 8 | Hello World! 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/multifile/multifile_hooks.coffee: -------------------------------------------------------------------------------- 1 | {after} = require 'hooks' 2 | 3 | after "Name API > /name > GET", (transaction) -> 4 | console.log "after name" 5 | 6 | after "Greeting API > /greeting > GET", (transaction) -> 7 | console.log "after greeting" 8 | 9 | after "Message API > /message > GET", (transaction) -> 10 | console.log "after message" 11 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/multifile/name.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Name API 4 | 5 | # GET /name 6 | + Response 200 (text/plain; charset=utf-8) 7 | 8 | Adam 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/multiple-examples.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines collection [/machines/{id}] 8 | + Parameters 9 | + id (number, `1`) 10 | 11 | ## Get Machines [GET] 12 | 13 | + Request (application/json) 14 | + Parameters 15 | + id (number, `2`) 16 | 17 | + Response 200 (application/json; charset=utf-8) 18 | 19 | [ 20 | { 21 | "type": "bulldozer", 22 | "name": "willy" 23 | } 24 | ] 25 | 26 | + Request (application/json) 27 | + Parameters 28 | + id (number, `3`) 29 | 30 | + Response 200 (application/json; charset=utf-8) 31 | 32 | [ 33 | { 34 | "type": "bulldozer", 35 | "name": "willy" 36 | } 37 | ] 38 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/multiple-responses.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Beehive API 5 | consumes: 6 | - application/json 7 | produces: 8 | - application/xml 9 | - application/json 10 | paths: 11 | /honey: 12 | get: 13 | responses: 14 | 400: 15 | description: user error 16 | 500: 17 | description: server error 18 | 200: 19 | description: pet response 20 | headers: 21 | X-Test: 22 | type: string 23 | enum: 24 | - Adam 25 | - Pavan 26 | schema: 27 | $ref: '#/definitions/Bee' 28 | definitions: 29 | Bee: 30 | required: 31 | - id 32 | - name 33 | properties: 34 | id: 35 | type: integer 36 | format: int64 37 | name: 38 | type: string 39 | tag: 40 | type: string 41 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/non-js-hooks.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/non-js-hooks.rb -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/openapi2-multiple-responses.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.before('/honey > GET > 500 > application/json', (transaction, done) => { 4 | transaction.skip = false; 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/openapi2-transaction-names.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | function logTransactionName(transaction, done) { 4 | hooks.log(transaction.name); 5 | done(); 6 | } 7 | 8 | hooks.before('/honey > GET > 400 > application/json', logTransactionName); 9 | hooks.before('/honey > GET > 500 > application/json', logTransactionName); 10 | hooks.before('/honey > GET > 200 > application/json', logTransactionName); 11 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/regression-152.coffee: -------------------------------------------------------------------------------- 1 | hooks = require 'hooks' 2 | 3 | # New hooks helper function 4 | hooks.beforeEach = (hookFn) -> 5 | hooks.beforeAll (done) -> 6 | for transactionKey, transaction of hooks.transactions or {} 7 | hooks.beforeHooks[transaction.name] ?= [] 8 | hooks.beforeHooks[transaction.name].unshift hookFn 9 | done() 10 | 11 | hooks.beforeEach (transaction) -> 12 | # add query parameter to each transaction here 13 | paramToAdd = "api-key=23456" 14 | if transaction.fullPath.indexOf('?') > -1 15 | transaction.fullPath += "&" + paramToAdd 16 | else 17 | transaction.fullPath += "?" + paramToAdd 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/regression-319-354.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Building Supply Store API 4 | 5 | ## Brick Type [/bricks/{id}] 6 | 7 | + Parameters 8 | + id: XYZ42 - ID of a brick type. 9 | + Attributes 10 | + id 11 | + name (string, required) 12 | + colors: red, brown (array) 13 | + Include DimensionsMixin 14 | + producer 15 | + Include AddressMixin 16 | 17 | ### Get Particular Brick Type [GET] 18 | 19 | Attributes defined in resource are referenced from payload. 20 | 21 | + Request (application/json) 22 | + Response 200 (application/json; charset=utf-8) 23 | + Attributes (Brick Type) 24 | 25 | ## Available Brick Types [/bricks] 26 | 27 | ### Create a New Brick Type [POST] 28 | 29 | Attributes defined in resource are referenced from action. 30 | 31 | + Attributes (Brick Type) 32 | + Request (application/json) 33 | + Response 200 (application/json; charset=utf-8) 34 | + Attributes (Brick Type) 35 | 36 | ## Customers [/customers] 37 | 38 | ### Get All Customers [GET] 39 | 40 | Attributes defined as data structure are referenced from payload. 41 | 42 | + Request (application/json) 43 | + Response 200 (application/json; charset=utf-8) 44 | + Attributes (array[Customer]) 45 | 46 | ### Add New Customer [POST] 47 | 48 | Attributes defined as data structure are referenced from action. 49 | 50 | + Attributes (Customer) 51 | + Request (application/json) 52 | + Response 200 (application/json; charset=utf-8) 53 | + Attributes (Customer) 54 | 55 | ## Data Structures 56 | 57 | ### User (object) 58 | 59 | + id 60 | + name (string) 61 | + shoeSize: 42 (number) 62 | 63 | ### Customer (User) 64 | 65 | + Include AddressMixin 66 | 67 | ### AddressMixin (object) 68 | 69 | + address 70 | + street 71 | + city (string, nullable) 72 | 73 | ### DimensionsMixin (object) 74 | 75 | + dimensions (array) 76 | + 20, 30, 40 (array[number]) 77 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/regression-615.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Beehive API 4 | 5 | ## Honey [/honey] 6 | 7 | ### Retrieve [GET] 8 | 9 | + Request (application/json) 10 | + Request (application/xml) 11 | + Response 200 12 | + Response 500 13 | 14 | ### Remove [DELETE] 15 | 16 | + Request (application/json) 17 | + Response 200 18 | + Response 403 19 | + Response 500 20 | 21 | + Request (text/plain) 22 | + Response 200 23 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/regression-893.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json; charset=utf-8 9 | paths: 10 | /resource: 11 | get: 12 | responses: 13 | default: 14 | description: Representation 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/regression-897-body.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json; charset=utf-8 9 | - text/csv; charset=utf-8 10 | paths: 11 | /resource: 12 | get: 13 | responses: 14 | 200: 15 | description: Representation 16 | /resource.csv: 17 | get: 18 | responses: 19 | 200: 20 | description: Representation 21 | examples: 22 | "text/csv; charset=utf-8": "" 23 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/regression-897-schema.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json; charset=utf-8 9 | - text/csv; charset=utf-8 10 | paths: 11 | /resource: 12 | get: 13 | responses: 14 | 200: 15 | description: Representation 16 | /resource.csv: 17 | get: 18 | responses: 19 | 200: 20 | description: Representation 21 | examples: 22 | "text/csv; charset=utf-8": "name,color\nHonza,green\n" 23 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/application-json.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Testing 'application/json' Request API 4 | 5 | # POST /data 6 | 7 | + Request (application/json) 8 | 9 | + Body 10 | 11 | {"test": 42} 12 | 13 | + Response 200 (application/json; charset=utf-8) 14 | 15 | + Body 16 | 17 | {"test": "OK"} 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/application-octet-stream-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.beforeEach((transaction, done) => { 4 | transaction.request.body = Buffer.from([0xFF, 0xEF, 0xBF, 0xBE]).toString('base64'); 5 | transaction.request.bodyEncoding = 'base64'; 6 | done(); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/application-octet-stream.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Binary API 4 | 5 | ## Resource [/binary] 6 | 7 | ### Send Binary Data [POST] 8 | 9 | + Request (application/octet-stream) 10 | 11 | + Response 200 (application/json; charset=utf-8) 12 | + Body 13 | 14 | {"test": "OK"} 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/application-octet-stream.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Binary API 5 | schemes: 6 | - http 7 | consumes: 8 | - application/octet-stream 9 | produces: 10 | - application/json 11 | paths: 12 | /binary: 13 | post: 14 | parameters: 15 | - name: binary 16 | in: body 17 | required: true 18 | schema: 19 | type: string 20 | format: binary 21 | responses: 22 | 200: 23 | description: 'Test OK' 24 | examples: 25 | application/json; charset=utf-8: 26 | test: 'OK' 27 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/application-x-www-form-urlencoded.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Testing 'application/x-www-form-urlencoded' Request API 4 | 5 | # POST /data 6 | 7 | + Request (application/x-www-form-urlencoded) 8 | 9 | + Body 10 | 11 | test=42 12 | 13 | + Response 200 (application/json; charset=utf-8) 14 | 15 | + Body 16 | 17 | {"test": "OK"} 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/application-x-www-form-urlencoded.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: "Testing 'application/x-www-form-urlencoded' Request API" 4 | version: '1.0' 5 | consumes: 6 | - application/x-www-form-urlencoded 7 | produces: 8 | - application/json; charset=utf-8 9 | paths: 10 | '/data': 11 | post: 12 | parameters: 13 | - name: test 14 | in: formData 15 | type: string 16 | required: true 17 | x-example: "42" 18 | responses: 19 | 200: 20 | description: 'Test OK' 21 | examples: 22 | application/json; charset=utf-8: 23 | test: 'OK' 24 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/image-png-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | 5 | hooks.beforeEach((transaction, done) => { 6 | const buffer = fs.readFileSync(path.join(__dirname, '../image.png')); 7 | transaction.request.body = buffer.toString('base64'); 8 | transaction.request.bodyEncoding = 'base64'; 9 | done(); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/image-png.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Images API 4 | 5 | ## Resource [/image.png] 6 | 7 | ### Send an Image [PUT] 8 | 9 | + Request (image/png) 10 | 11 | + Response 200 (application/json; charset=utf-8) 12 | + Body 13 | 14 | {"test": "OK"} 15 | 16 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/image-png.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Images API 5 | schemes: 6 | - http 7 | consumes: 8 | - image/png 9 | produces: 10 | - application/json 11 | paths: 12 | /image.png: 13 | put: 14 | parameters: 15 | - name: binary 16 | in: body 17 | required: true 18 | schema: 19 | type: string 20 | format: binary 21 | responses: 22 | 200: 23 | description: 'Test OK' 24 | examples: 25 | application/json; charset=utf-8: 26 | test: 'OK' 27 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/multipart-form-data-file.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: "Testing 'multipart/form-data' Request API" 4 | version: '1.0' 5 | consumes: 6 | - multipart/form-data 7 | produces: 8 | - application/json; charset=utf-8 9 | paths: 10 | '/data': 11 | post: 12 | parameters: 13 | - name: text 14 | in: formData 15 | type: file 16 | required: true 17 | x-example: "test equals to 42" 18 | - name: json 19 | in: formData 20 | type: file 21 | required: true 22 | x-example: '{"test": 42}' 23 | responses: 24 | 200: 25 | description: 'Test OK' 26 | examples: 27 | application/json; charset=utf-8: 28 | test: 'OK' 29 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/multipart-form-data.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Testing 'multipart/form-data' Request API 4 | 5 | # POST /data 6 | 7 | + Request (multipart/form-data; boundary=CUSTOM-BOUNDARY) 8 | 9 | + Body 10 | 11 | --CUSTOM-BOUNDARY 12 | Content-Disposition: form-data; name="text" 13 | Content-Type: text/plain 14 | 15 | test equals to 42 16 | --CUSTOM-BOUNDARY 17 | Content-Disposition: form-data; name="json" 18 | Content-Type: application/json 19 | 20 | {"test": 42} 21 | 22 | --CUSTOM-BOUNDARY-- 23 | 24 | + Response 200 (application/json; charset=utf-8) 25 | 26 | + Body 27 | 28 | {"test": "OK"} 29 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/multipart-form-data.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: "Testing 'multipart/form-data' Request API" 4 | version: '1.0' 5 | consumes: 6 | - multipart/form-data; boundary=CUSTOM-BOUNDARY 7 | produces: 8 | - application/json; charset=utf-8 9 | paths: 10 | '/data': 11 | post: 12 | parameters: 13 | - name: text 14 | in: formData 15 | type: string 16 | required: true 17 | x-example: "test equals to 42" 18 | - name: json 19 | in: formData 20 | type: string 21 | required: true 22 | x-example: '{"test": 42}' 23 | responses: 24 | 200: 25 | description: 'Test OK' 26 | examples: 27 | application/json; charset=utf-8: 28 | test: 'OK' 29 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/request/text-plain.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Testing 'text/plain' Request API 4 | 5 | # POST /data 6 | 7 | + Request (text/plain) 8 | 9 | + Body 10 | 11 | test equals to 42 12 | 13 | + Response 200 (application/json; charset=utf-8) 14 | 15 | + Body 16 | 17 | {"test": "OK"} 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/requiredModule.js: -------------------------------------------------------------------------------- 1 | global.__requiredModule = true; 2 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/204-205-body.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource 204 without Body [/204-without-body] 6 | ### Retrieve Representation [GET] 7 | 8 | + Response 204 9 | 10 | ## Resource 205 without Body [/205-without-body] 11 | ### Retrieve Representation [GET] 12 | 13 | + Response 205 14 | 15 | ## Resource 204 with Body [/204-with-body] 16 | ### Retrieve Representation [GET] 17 | 18 | + Response 204 (text/plain; charset=utf-8) 19 | + Body 20 | 21 | test 22 | 23 | ## Resource 205 with Body [/205-with-body] 24 | ### Retrieve Representation [GET] 25 | 26 | + Response 205 (text/plain; charset=utf-8) 27 | + Body 28 | 29 | test 30 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/204-205-body.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - text/plain; charset=utf-8 9 | paths: 10 | /204-without-body: 11 | get: 12 | responses: 13 | 204: 14 | description: Representation 15 | /205-without-body: 16 | get: 17 | responses: 18 | 205: 19 | description: Representation 20 | /204-with-body: 21 | get: 22 | responses: 23 | 204: 24 | description: Representation 25 | examples: 26 | "text/plain; charset=utf-8": "test\n" 27 | /205-with-body: 28 | get: 29 | responses: 30 | 205: 31 | description: Representation 32 | examples: 33 | "text/plain; charset=utf-8": "test\n" 34 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/binary-assert-body-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | 5 | hooks.beforeEachValidation((transaction, done) => { 6 | const bytes = fs.readFileSync(path.join(__dirname, '../image.png')); 7 | transaction.expected.body = bytes.toString('base64'); 8 | done(); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/binary-ignore-body-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.beforeEachValidation((transaction, done) => { 4 | transaction.real.body = ''; 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/binary.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Images API 4 | 5 | ## Resource [/image.png] 6 | 7 | ### Retrieve Representation [GET] 8 | 9 | + Response 200 (image/png) 10 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/binary.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Images API 5 | schemes: 6 | - http 7 | produces: 8 | - image/png 9 | paths: 10 | /image.png: 11 | get: 12 | responses: 13 | 200: 14 | description: Representation 15 | schema: 16 | type: string 17 | format: binary 18 | examples: 19 | "image/png": "" 20 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/empty-body-empty-schema.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource [/resource.json] 6 | 7 | ### Retrieve Representation [GET] 8 | 9 | + Response 200 (application/json; charset=utf-8) 10 | 11 | ## Resource [/resource.csv] 12 | 13 | ### Retrieve Representation [GET] 14 | 15 | + Response 200 (text/csv; charset=utf-8) 16 | + Body 17 | 18 | ``` 19 | ``` 20 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/empty-body-empty-schema.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json; charset=utf-8 9 | - text/csv; charset=utf-8 10 | paths: 11 | /resource.json: 12 | get: 13 | responses: 14 | 200: 15 | description: Representation 16 | /resource.csv: 17 | get: 18 | responses: 19 | 200: 20 | description: Representation 21 | examples: 22 | "text/csv; charset=utf-8": "" 23 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/empty-body-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.beforeEachValidation((transaction, done) => { 4 | if (transaction.real.body) { 5 | transaction.fail = 'The response body must be empty'; 6 | } 7 | done(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/empty-body.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # My API 4 | 5 | ## Resource [/resource] 6 | 7 | ### Retrieve Representation [GET] 8 | 9 | + Response 200 (application/json; charset=utf-8) 10 | + Schema 11 | 12 | { 13 | "type": "object", 14 | "properties": {"name": {"type": "string"}}, 15 | "required": ["name"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/response/empty-body.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | version: "1.0" 4 | title: Colors API 5 | schemes: 6 | - http 7 | produces: 8 | - application/json; charset=utf-8 9 | paths: 10 | /resource: 11 | get: 12 | responses: 13 | 200: 14 | description: Representation 15 | schema: 16 | type: object 17 | properties: 18 | name: {type: string} 19 | required: [name] 20 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/any-content-guard-pattern-matching.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | 5 | # Resource [/resource{?token}] 6 | 7 | + Parameters 8 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 9 | 10 | ## Update Resource [PUT] 11 | 12 | + Request (application/json) 13 | 14 | + Headers 15 | 16 | Authorization: token 5229c6e8e4b0bd7dbb07e29c 17 | 18 | + Attributes 19 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 20 | + name: `Alice` (string) 21 | 22 | + Response 200 (application/json; charset=utf-8) 23 | 24 | + Headers 25 | 26 | Authorization: token 5229c6e8e4b0bd7dbb07e29c 27 | 28 | + Attributes 29 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 30 | + name: `Alice` (string) 31 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/any-content-guard-pattern-matching.js: -------------------------------------------------------------------------------- 1 | const assert = require('chai').assert; 2 | const hooks = require('hooks'); 3 | 4 | const tokenPattern = /([0-9]|[a-f]){24,}/g; 5 | 6 | hooks.beforeEach((transaction, done) => { 7 | transaction.id = transaction.id.replace(tokenPattern, 'CENSORED'); 8 | transaction.origin.resourceName = transaction.origin.resourceName.replace(tokenPattern, 'CENSORED'); 9 | done(); 10 | }); 11 | 12 | hooks.afterEach((transaction, done) => { 13 | try { 14 | JSON.stringify(transaction.test, (key, value) => { 15 | if (typeof value === 'string') { 16 | assert.notMatch(value, tokenPattern); 17 | } 18 | return value; 19 | }); 20 | } catch (error) { 21 | transaction.fail = 'Sensitive data would be sent to Dredd reporter'; 22 | transaction.test = { 23 | start: transaction.test.start, 24 | end: transaction.test.end, 25 | duration: transaction.test.duration, 26 | startedAt: transaction.test.startedAt, 27 | message: transaction.fail, 28 | }; 29 | } 30 | done(); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/any-content-pattern-matching.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | 5 | # Resource [/resource{?token}] 6 | 7 | + Parameters 8 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 9 | 10 | ## Update Resource [PUT] 11 | 12 | + Request (application/json) 13 | 14 | + Headers 15 | 16 | Authorization: token 5229c6e8e4b0bd7dbb07e29c 17 | 18 | + Attributes 19 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 20 | + name: `Alice` (string) 21 | 22 | + Response 200 (application/json; charset=utf-8) 23 | 24 | + Headers 25 | 26 | Authorization: token 5229c6e8e4b0bd7dbb07e29c 27 | 28 | + Attributes 29 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 30 | + name: `Alice` (string) 31 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/any-content-pattern-matching.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | const tokenPattern = /([0-9]|[a-f]){24,}/g; 4 | 5 | hooks.beforeEach((transaction, done) => { 6 | transaction.id = transaction.id.replace(tokenPattern, 'CENSORED'); 7 | transaction.origin.resourceName = transaction.origin.resourceName.replace(tokenPattern, 'CENSORED'); 8 | done(); 9 | }); 10 | 11 | hooks.afterEach((transaction, done) => { 12 | const test = JSON.stringify(transaction.test, (key, value) => { 13 | if (value.replace) { 14 | return value.replace(tokenPattern, 'CENSORED'); 15 | } 16 | return value; 17 | }); 18 | transaction.test = JSON.parse(test); 19 | done(); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/entire-request-body.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/entire-request-body.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | transaction.test.request.body = ''; 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/entire-response-body.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + name: `Alice` (string) 10 | 11 | + Response 200 (application/json; charset=utf-8) 12 | + Attributes 13 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/entire-response-body.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | transaction.test.actual.body = ''; 5 | transaction.test.expected.body = ''; 6 | transaction.test.expected.bodySchema = ''; 7 | 8 | transaction.test.message = ''; 9 | delete transaction.test.results.fields.body; 10 | done(); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/plain-text-response-body.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (text/plain) 8 | 9 | + Response 200 (text/plain; charset=utf-8) 10 | + Body 11 | 12 | token=5229c6e8e4b0bd7dbb07e29c 13 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/plain-text-response-body.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | const tokenPattern = /([0-9]|[a-f]){24,}/g; 4 | 5 | hooks.after('Resource > Update Resource', (transaction, done) => { 6 | const replaceToken = body => body.replace(tokenPattern, '--- CENSORED ---'); 7 | 8 | // Remove sensitive data from Dredd transaction 9 | transaction.test.actual.body = replaceToken(transaction.test.actual.body); 10 | transaction.test.expected.body = replaceToken(transaction.test.expected.body); 11 | 12 | // Remove sensitive data from the Gavel validation result 13 | const bodyResult = transaction.test.results.fields.body; 14 | bodyResult.values.expected = replaceToken(bodyResult.values.expected); 15 | bodyResult.values.actual = replaceToken(bodyResult.values.actual); 16 | 17 | done(); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/request-body-attribute.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/request-body-attribute.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | const body = JSON.parse(transaction.test.request.body); 5 | delete body.token; 6 | transaction.test.request.body = JSON.stringify(body); 7 | done(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/request-headers.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Headers 9 | 10 | Authorization: token 5229c6e8e4b0bd7dbb07e29c 11 | 12 | + Attributes 13 | + name: `Alice` (string) 14 | 15 | + Response 200 (application/json; charset=utf-8) 16 | + Attributes 17 | + name: `Alice` (string) 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/request-headers.js: -------------------------------------------------------------------------------- 1 | const caseless = require('caseless'); 2 | const hooks = require('hooks'); 3 | 4 | hooks.after('Resource > Update Resource', (transaction, done) => { 5 | const headers = transaction.test.request.headers; 6 | const name = caseless(headers).has('Authorization'); 7 | delete headers[name]; 8 | transaction.test.request.headers = headers; 9 | done(); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/response-body-attribute.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + name: `Alice` (string) 10 | 11 | + Response 200 (application/json; charset=utf-8) 12 | + Attributes 13 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/response-body-attribute.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | const unfold = (jsonString, transform) => JSON.stringify(transform(JSON.parse(jsonString))); 4 | 5 | hooks.after('Resource > Update Resource', (transaction, done) => { 6 | const deleteToken = (obj) => { 7 | delete obj.token; 8 | return obj; 9 | }; 10 | 11 | // Removes sensitive data from the Dredd transaction 12 | transaction.test.actual.body = unfold(transaction.test.actual.body, deleteToken); 13 | transaction.test.expected.body = unfold(transaction.test.expected.body, deleteToken); 14 | 15 | // Sanitation of the attribute in JSON Schema 16 | const bodySchema = JSON.parse(transaction.test.expected.bodySchema); 17 | delete bodySchema.properties.token; 18 | transaction.test.expected.bodySchema = JSON.stringify(bodySchema); 19 | 20 | // Removes sensitive data from the Gavel validation result 21 | const bodyResult = transaction.test.results.fields.body; 22 | bodyResult.errors = bodyResult.errors.filter(error => error.location.pointer !== '/token'); 23 | bodyResult.values.expected = unfold(bodyResult.values.expected, deleteToken); 24 | bodyResult.values.actual = unfold(bodyResult.values.actual, deleteToken); 25 | 26 | transaction.test.message = ''; 27 | done(); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/response-headers.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + name: `Alice` (string) 10 | 11 | + Response 200 (application/json; charset=utf-8) 12 | + Headers 13 | 14 | Authorization: token 5229c6e8e4b0bd7dbb07e29c 15 | 16 | + Attributes 17 | + name: `Alice` (string) 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/response-headers.js: -------------------------------------------------------------------------------- 1 | const caseless = require('caseless'); 2 | const hooks = require('hooks'); 3 | 4 | hooks.after('Resource > Update Resource', (transaction, done) => { 5 | const deleteSensitiveHeader = (headerName, headers) => { 6 | const name = caseless(headers).has(headerName); 7 | delete headers[name]; 8 | return headers; 9 | }; 10 | 11 | // Remove sensitive data from the Dredd transaction 12 | transaction.test.actual.headers = deleteSensitiveHeader('authorization', transaction.test.actual.headers); 13 | transaction.test.expected.headers = deleteSensitiveHeader('authorization', transaction.test.expected.headers); 14 | 15 | // Remove sensitive data from the Gavel validation result 16 | const headersResult = transaction.test.results.fields.headers; 17 | headersResult.errors = headersResult.errors.filter(error => error.location.pointer.toLowerCase() !== '/authorization'); 18 | headersResult.values.expected = deleteSensitiveHeader('authorization', headersResult.values.expected); 19 | 20 | transaction.test.message = ''; 21 | done(); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-erroring-hooks.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-erroring-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | JSON.parse('💥 boom 💥'); 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-marked-failed-after.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-marked-failed-after.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | transaction.test.request.body = ''; 5 | transaction.fail = true; 6 | done(); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-marked-failed-before.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-marked-failed-before.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.before('Resource > Update Resource', (transaction, done) => { 4 | transaction.fail = true; 5 | done(); 6 | }); 7 | 8 | hooks.after('Resource > Update Resource', (transaction, done) => { 9 | if (transaction.test && transaction.test.request) { 10 | transaction.test.request.body = ''; 11 | } 12 | done(); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-marked-skipped.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-marked-skipped.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.before('Resource > Update Resource', (transaction, done) => { 4 | transaction.skip = true; 5 | done(); 6 | }); 7 | 8 | hooks.after('Resource > Update Resource', (transaction, done) => { 9 | if (transaction.test && transaction.test.request) { 10 | transaction.test.request.body = ''; 11 | } 12 | done(); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-passing.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-passing.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | transaction.test.request.body = ''; 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-secured-erroring-hooks.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # Resource [/resource] 5 | ## Update Resource [PUT] 6 | 7 | + Request (application/json) 8 | + Attributes 9 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 10 | + name: `Alice` (string) 11 | 12 | + Response 200 (application/json; charset=utf-8) 13 | + Attributes 14 | + name: `Alice` (string) 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/transaction-secured-erroring-hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.after('Resource > Update Resource', (transaction, done) => { 4 | try { 5 | JSON.parse('💥 boom 💥'); 6 | } catch (error) { 7 | transaction.fail = 'Unexpected exception in hooks'; 8 | transaction.test = { 9 | start: transaction.test.start, 10 | end: transaction.test.end, 11 | duration: transaction.test.duration, 12 | startedAt: transaction.test.startedAt, 13 | message: transaction.fail, 14 | }; 15 | } 16 | done(); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/uri-parameters.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Top Secret API 4 | # PUT /resource{?token} 5 | 6 | + Parameters 7 | + token: `5229c6e8e4b0bd7dbb07e29c` (string) 8 | 9 | + Request (application/json) 10 | + Attributes 11 | + name: `Alice` (string) 12 | 13 | + Response 200 (application/json; charset=utf-8) 14 | + Attributes 15 | + name: `Alice` (string) 16 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/sanitation/uri-parameters.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | const tokenPattern = /([0-9]|[a-f]){24,}/g; 4 | 5 | hooks.beforeEach((transaction, done) => { 6 | transaction.id = transaction.id.replace(tokenPattern, 'CENSORED'); 7 | transaction.origin.resourceName = transaction.origin.resourceName.replace(tokenPattern, 'CENSORED'); 8 | done(); 9 | }); 10 | 11 | hooks.afterEach((transaction, done) => { 12 | transaction.test.request.uri = transaction.test.request.uri.replace(tokenPattern, 'CENSORED'); 13 | done(); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/schema.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # API 4 | Demonstrates dredd schema test issue [#46](https://github.com/apiaryio/dredd/issues/46). Original API blueprint by @mgaut72. 5 | 6 | # Group Session 7 | 8 | ## Session [/] 9 | 10 | ### Log a user in [GET] 11 | + Response 200 (application/json; charset=utf-8) 12 | 13 | + Body 14 | 15 | { 16 | "data": { 17 | "token": "234khsdfs9d8fsdf", 18 | "expires": 1424641830 19 | } 20 | } 21 | 22 | + Schema 23 | 24 | { 25 | "type":"object", 26 | "required":["data"], 27 | "properties":{ 28 | "data": { 29 | "type":"object", 30 | "required":["expires","token"], 31 | "properties":{ 32 | "expires": { 33 | "type":"number" 34 | }, 35 | "token": { 36 | "type":"string" 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/dummy-server-crash.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | 5 | app.get('/machines', (req, res) => { 6 | res.json([{ type: 'bulldozer', name: 'willy' }]); 7 | }); 8 | 9 | app.get('/machines/:name', () => { 10 | process.exit(1); 11 | }); 12 | 13 | app.listen(process.argv[2], () => { 14 | console.log(`Dummy server listening on port ${process.argv[2]}!`); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/dummy-server-ignore-term.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | require('./handle-windows-sigint.js')(); 4 | 5 | function ignore() { 6 | console.log('ignoring termination'); 7 | } 8 | 9 | process.on('SIGTERM', ignore); 10 | process.on('SIGINT', ignore); 11 | 12 | const app = express(); 13 | 14 | app.get('/machines', (req, res) => { 15 | res.json([{ type: 'bulldozer', name: 'willy' }]); 16 | }); 17 | 18 | app.get('/machines/:name', (req, res) => { 19 | res.json({ type: 'bulldozer', name: req.params.name }); 20 | }); 21 | 22 | app.listen(process.argv[2], () => { 23 | console.log(`Dummy server listening on port ${process.argv[2]}!`); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/dummy-server-kill.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | 5 | app.get('/machines', (req, res) => { 6 | res.json([{ type: 'bulldozer', name: 'willy' }]); 7 | }); 8 | 9 | app.get('/machines/:name', () => { 10 | process.kill(process.pid, 'SIGKILL'); 11 | }); 12 | 13 | app.listen(process.argv[2], () => { 14 | console.log(`Dummy server listening on port ${process.argv[2]}!`); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/dummy-server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | 5 | app.get('/machines', (req, res) => { 6 | res.json([{ type: 'bulldozer', name: 'willy' }]); 7 | }); 8 | 9 | app.get('/machines/:name', (req, res) => { 10 | res.json({ type: 'bulldozer', name: req.params.name }); 11 | }); 12 | 13 | app.listen(process.argv[2], () => { 14 | console.log(`Dummy server listening on port ${process.argv[2]}!`); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/emptyfile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apiaryio/dredd/3d4ae1431397990603285617fa5f7ddb81dc3992/packages/dredd/test/fixtures/scripts/emptyfile -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/endless-ignore-term.coffee: -------------------------------------------------------------------------------- 1 | require('./handle-windows-sigint.js')() 2 | 3 | ignore = -> 4 | console.log('ignoring termination') 5 | 6 | process.on('SIGTERM', ignore) 7 | process.on('SIGINT', ignore) 8 | 9 | setInterval(( -> ), 1000) 10 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/exit-0.coffee: -------------------------------------------------------------------------------- 1 | process.exit(0) 2 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/exit-3.js: -------------------------------------------------------------------------------- 1 | process.exit(3); 2 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/handle-windows-sigint.js: -------------------------------------------------------------------------------- 1 | const readline = require('readline'); 2 | 3 | const ASCII_CTRL_C = 3; 4 | 5 | // To learn about why this is needed and how it works, see 6 | // the 'lib/childProcess.js' file, function 'signalTerm'. 7 | module.exports = () => { 8 | // Handling programmatic interruption (Dredd sends '\u0003' 9 | // to stdin) 10 | process.stdin.on('data', (chunk) => { 11 | for (const char of chunk.toString()) { 12 | if (char.charCodeAt(0) === ASCII_CTRL_C) { 13 | process.emit('SIGINT'); 14 | break; 15 | } 16 | } 17 | }); 18 | 19 | // Handling manual interruption (user sends '\u0003' to stdin by 20 | // manually pressing Ctrl+C) 21 | const rl = readline.createInterface({ 22 | input: process.stdin, 23 | output: process.stdout, 24 | }); 25 | rl.on('SIGINT', () => { 26 | process.emit('SIGINT'); 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/kill-self.js: -------------------------------------------------------------------------------- 1 | setTimeout(() => { 2 | process.kill(process.pid, 'SIGKILL'); 3 | }, 100); 4 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/stderr.coffee: -------------------------------------------------------------------------------- 1 | require('./handle-windows-sigint')() 2 | 3 | exit = -> 4 | process.stdout.write('exiting\n') 5 | process.exit(0) 6 | 7 | process.on('SIGTERM', exit) 8 | process.on('SIGINT', exit) 9 | 10 | process.stderr.write('error output text\n') 11 | setInterval(( -> ), 100) 12 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/stdout-exit-3.coffee: -------------------------------------------------------------------------------- 1 | require('./handle-windows-sigint.js')() 2 | 3 | exit = -> 4 | process.stdout.write('exiting\n') 5 | process.exit(3) 6 | 7 | process.on('SIGTERM', exit) 8 | process.on('SIGINT', exit) 9 | 10 | process.stdout.write('standard output text\n') 11 | setInterval(( -> ), 100) 12 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/scripts/stdout.coffee: -------------------------------------------------------------------------------- 1 | require('./handle-windows-sigint.js')() 2 | 3 | exit = -> 4 | process.stdout.write('exiting\n') 5 | process.exit(0) 6 | 7 | process.on('SIGTERM', exit) 8 | process.on('SIGINT', exit) 9 | 10 | process.stdout.write('standard output text\n') 11 | setInterval(( -> ), 100) 12 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/simple-unnamed.apib: -------------------------------------------------------------------------------- 1 | # GET /message 2 | + Response 200 (text/plain) 3 | 4 | Hello World! 5 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/single-get-nogroup.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Machines collection [/machines] 6 | 7 | ## Get Machines [GET] 8 | 9 | - Response 200 (application/json; charset=utf-8) 10 | 11 | [ 12 | { 13 | "type": "bulldozer", 14 | "name": "willy" 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/single-get-path.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machine [/machines/caterpillar] 8 | 9 | ## Get Machine [GET] 10 | 11 | - Response 200 (application/json; charset=utf-8) 12 | 13 | { 14 | "type": "bulldozer", 15 | "name": "caterpillar" 16 | } 17 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/single-get-uri-template.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machine [/machines/{name}] 8 | 9 | + Parameters 10 | + name (required,`willy`) 11 | 12 | ## Get Machine [GET] 13 | 14 | - Response 200 (application/json; charset=utf-8) 15 | 16 | { 17 | "type": "bulldozer", 18 | "name": "willy" 19 | } 20 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/single-get.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines collection [/machines] 8 | 9 | ## Get Machines [GET] 10 | 11 | - Response 200 (application/json; charset=utf-8) 12 | 13 | [ 14 | { 15 | "type": "bulldozer", 16 | "name": "willy" 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/single-get.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Machines API 4 | version: '1.0' 5 | paths: 6 | '/machines': 7 | x-summary: Machines Collection 8 | get: 9 | summary: Get Machines 10 | description: Retrieve Machines list 11 | responses: 12 | 200: 13 | description: Machine list response 14 | schema: 15 | type: array 16 | items: {} 17 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/test2_all.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.beforeAll((done) => { 4 | console.log('*** beforeAll'); 5 | done(); 6 | }); 7 | 8 | hooks.before( 9 | 'Machines > Machines collection > Get Machines', 10 | (transaction, done) => { 11 | console.log('*** before'); 12 | done(); 13 | }, 14 | ); 15 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/test2_events.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.beforeAll((done) => { 4 | console.log('hooks.beforeAll'); 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/test2_hooks.js: -------------------------------------------------------------------------------- 1 | const hooks = require('hooks'); 2 | 3 | hooks.before( 4 | 'Machines > Machines collection > Get Machines', 5 | (transaction, done) => { 6 | transaction.request.headers.header = '123232323'; 7 | console.log('before'); 8 | done(); 9 | }, 10 | ); 11 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/test_all.coffee: -------------------------------------------------------------------------------- 1 | {after,afterAll} = require 'hooks' 2 | 3 | after "Machines > Machines collection > Get Machines", (transaction) -> 4 | console.log "*** after" 5 | 6 | afterAll (done) -> 7 | console.log "*** afterAll" 8 | done() 9 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/test_events.js: -------------------------------------------------------------------------------- 1 | const { afterAll } = require('hooks'); 2 | 3 | afterAll((done) => { 4 | console.log('hooks.afterAll'); 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/test_hooks.coffee: -------------------------------------------------------------------------------- 1 | {after} = require 'hooks' 2 | 3 | after "Machines > Machines collection > Get Machines", (transaction) -> 4 | console.log "after" 5 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/warning-ambiguous.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | # Group Machines 5 | # Machine [/machines/{name}] 6 | ## Retrieve Single Machine [GET] 7 | 8 | + Response 200 (application/json; charset=utf-8) 9 | 10 | { 11 | "type": "bulldozer", 12 | "name": "willy" 13 | } 14 | 15 | # Machines [/machines/{?sort}] 16 | ## Retrieve All Machines [GET] 17 | 18 | + Response 200 (application/json; charset=utf-8) 19 | 20 | [{ 21 | "type": "bulldozer", 22 | "name": "willy" 23 | }] 24 | 25 | # Machine Types [/machine-types/] 26 | ## Create a New Machine Type [POST] 27 | 28 | + Request (application/json; charset=utf-8) 29 | 30 | { 31 | "name": "bulldozer" 32 | } 33 | 34 | + Response 200 (application/json; charset=utf-8) 35 | 36 | [{ 37 | "name": "bulldozer" 38 | }] 39 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/warning-blueprint.apib: -------------------------------------------------------------------------------- 1 | FORMAT: 1A 2 | 3 | # Machines API 4 | 5 | # Group Machines 6 | 7 | # Machines collection [/machines/{?sort}] 8 | 9 | ## Get Machines [GET] 10 | 11 | + Response 200 (application/json; charset=utf-8) 12 | 13 | [{ 14 | "type": "bulldozer", 15 | "name": "willy" 16 | }] 17 | -------------------------------------------------------------------------------- /packages/dredd/test/fixtures/warning-openapi2.yaml: -------------------------------------------------------------------------------- 1 | swagger: '2.0' 2 | info: 3 | title: Machines API 4 | version: '1.0' 5 | host: api.example.com 6 | schemes: 7 | - https 8 | - http 9 | paths: 10 | '/machines': 11 | x-summary: Machines Collection 12 | get: 13 | summary: Get Machines 14 | description: Retrieve Machines list 15 | externalDocs: 16 | url: https://google.com 17 | responses: 18 | 200: 19 | description: Machine list response 20 | schema: 21 | type: array 22 | items: {} 23 | -------------------------------------------------------------------------------- /packages/dredd/test/integration/regressions/regression-152-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import Dredd from '../../../lib/Dredd' 4 | import { runDreddWithServer, createServer } from '../helpers' 5 | 6 | describe('Regression: Issue #152', () => 7 | describe('Modify transaction object inside beforeAll combined with beforeEach helper', () => { 8 | let runtimeInfo 9 | 10 | before((done) => { 11 | const app = createServer() 12 | app.get('/machines', (req, res) => 13 | res.json([{ type: 'bulldozer', name: 'willy' }]) 14 | ) 15 | 16 | const dredd = new Dredd({ 17 | options: { 18 | path: './test/fixtures/single-get.apib', 19 | require: 'coffeescript/register', 20 | hookfiles: './test/fixtures/regression-152.coffee' 21 | } 22 | }) 23 | 24 | runDreddWithServer(dredd, app, (...args) => { 25 | let err 26 | // eslint-disable-next-line 27 | ;[err, runtimeInfo] = Array.from(args) 28 | done(err) 29 | }) 30 | }) 31 | 32 | it('should modify the transaction with hooks', () => 33 | assert.deepEqual(Object.keys(runtimeInfo.server.requests), [ 34 | '/machines?api-key=23456' 35 | ])) 36 | })) 37 | -------------------------------------------------------------------------------- /packages/dredd/test/integration/regressions/regression-531-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | 3 | import { runDreddWithServer, createServer } from '../helpers'; 4 | import Dredd from '../../../lib/Dredd'; 5 | 6 | describe(`Sending and receiving "application/hal+json" according to produces/consumes in OpenAPI 2.0`, () => { 7 | let runtimeInfo; 8 | 9 | before((done) => { 10 | const app = createServer(); 11 | app.get('/articles', (req, res) => 12 | res 13 | .set({ 14 | 'content-type': 'application/hal+json', 15 | }) 16 | .json([ 17 | { 18 | id: 1, 19 | title: 'Creamy', 20 | text: 'Arbitrary', 21 | _links: { 22 | self: { 23 | href: '/articles/1', 24 | }, 25 | }, 26 | }, 27 | ]), 28 | ); 29 | app.post('/articles', (req, res) => { 30 | res.status(201).json({ 31 | id: 2, 32 | title: 'Crispy schnitzel', 33 | text: 'Prepare eggs...', 34 | }); 35 | }); 36 | 37 | const dredd = new Dredd({ 38 | options: { 39 | path: './test/fixtures/531-produces-consumes.yaml', 40 | }, 41 | }); 42 | 43 | runDreddWithServer(dredd, app, (err, info) => { 44 | runtimeInfo = info; 45 | done(err); 46 | }); 47 | }); 48 | 49 | it('results in one passed request test', () => { 50 | assert.equal(runtimeInfo.dredd.stats.passes, 1); 51 | assert.include(runtimeInfo.dredd.logging, 'pass: GET (200) /articles'); 52 | }); 53 | 54 | it('results in one failed response test', () => { 55 | assert.equal(runtimeInfo.dredd.stats.failures, 1); 56 | assert.include(runtimeInfo.dredd.logging, 'fail: POST (201) /articles'); 57 | assert.include( 58 | runtimeInfo.dredd.logging, 59 | `fail: headers: At '/content-type' No enum match for: "application/json; charset=utf-8"`, 60 | ); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/dredd/test/integration/regressions/regression-615-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import Dredd from '../../../lib/Dredd' 4 | import { runDreddWithServer, createServer } from '../helpers' 5 | 6 | describe('Regression: Issue #615', () => { 7 | let runtimeInfo 8 | 9 | before((done) => { 10 | const app = createServer() 11 | app.all('/honey', (req, res) => 12 | res 13 | .status(200) 14 | .type('text/plain') 15 | .send('') 16 | ) 17 | 18 | const dredd = new Dredd({ 19 | options: { path: './test/fixtures/regression-615.apib' } 20 | }) 21 | runDreddWithServer(dredd, app, (...args) => { 22 | let err 23 | // eslint-disable-next-line 24 | ;[err, runtimeInfo] = Array.from(args) 25 | done(err) 26 | }) 27 | }) 28 | 29 | it('outputs no failures', () => 30 | assert.equal(runtimeInfo.dredd.stats.failures, 0)) 31 | it('results in exactly three tests', () => 32 | assert.equal(runtimeInfo.dredd.stats.tests, 3)) 33 | it('results in three passing tests', () => { 34 | // Ensures just the 200 responses were selected, because the server returns only 200s 35 | assert.equal(runtimeInfo.dredd.stats.passes, 3) 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /packages/dredd/test/mocha.opts: -------------------------------------------------------------------------------- 1 | --timeout=120000 2 | --recursive 3 | --require ./test/ts-node.js 4 | -------------------------------------------------------------------------------- /packages/dredd/test/ts-node.js: -------------------------------------------------------------------------------- 1 | require('ts-node').register({ 2 | // This path is relative to the CWD of "mocha" process, 3 | // which is, usually, the root directory of the repo. 4 | project: './test/tsconfig.json', 5 | transpileOnly: true, 6 | }); 7 | -------------------------------------------------------------------------------- /packages/dredd/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "esnext", 6 | "allowSyntheticDefaultImports": true, 7 | "allowJs": true, 8 | "noEmit": true, 9 | "rootDir": "../" 10 | }, 11 | "include": ["./**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/getProxySettings-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | 3 | import getProxySettings from '../../lib/getProxySettings'; 4 | 5 | describe('getProxySettings()', () => { 6 | it('detects HTTP_PROXY', () => { 7 | assert.deepEqual( 8 | getProxySettings({ 9 | SHELL: '/bin/bash', 10 | USER: 'honza', 11 | HTTP_PROXY: 'http://proxy.example.com:8080', 12 | }), 13 | ['HTTP_PROXY=http://proxy.example.com:8080'], 14 | ); 15 | }); 16 | 17 | it('detects HTTPS_PROXY', () => { 18 | assert.deepEqual( 19 | getProxySettings({ 20 | SHELL: '/bin/bash', 21 | USER: 'honza', 22 | HTTPS_PROXY: 'https://proxy.example.com:8080', 23 | }), 24 | ['HTTPS_PROXY=https://proxy.example.com:8080'], 25 | ); 26 | }); 27 | 28 | it('detects NO_PROXY', () => { 29 | assert.deepEqual( 30 | getProxySettings({ 31 | SHELL: '/bin/bash', 32 | USER: 'honza', 33 | NO_PROXY: '*', 34 | }), 35 | ['NO_PROXY=*'], 36 | ); 37 | }); 38 | 39 | it('detects both lower and upper case', () => { 40 | assert.deepEqual( 41 | getProxySettings({ 42 | SHELL: '/bin/bash', 43 | USER: 'honza', 44 | http_proxy: 'http://proxy.example.com:8080', 45 | NO_PROXY: '*', 46 | }), 47 | ['http_proxy=http://proxy.example.com:8080', 'NO_PROXY=*'], 48 | ); 49 | }); 50 | 51 | it('skips environment variables set to empty strings', () => { 52 | assert.deepEqual( 53 | getProxySettings({ 54 | SHELL: '/bin/bash', 55 | USER: 'honza', 56 | http_proxy: 'http://proxy.example.com:8080', 57 | NO_PROXY: '', 58 | }), 59 | ['http_proxy=http://proxy.example.com:8080'], 60 | ); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/detectApiDescription-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { detectApiDescription } from '../../../lib/init' 4 | 5 | describe('init._detectApiDescription()', () => { 6 | it('defaults to API Blueprint on empty array', () => 7 | assert.equal(detectApiDescription([]), 'apiary.apib')) 8 | 9 | it('defaults to API Blueprint on arbitrary files', () => 10 | assert.equal(detectApiDescription(['foo', 'bar']), 'apiary.apib')) 11 | 12 | it('detects the first API Blueprint file', () => 13 | assert.equal( 14 | detectApiDescription(['foo', 'boo.apib', 'bar', 'moo.apib']), 15 | 'boo.apib' 16 | )) 17 | 18 | it("detects the first .yml file containing 'swagger' as OpenAPI 2", () => 19 | assert.equal( 20 | detectApiDescription(['foo', 'this-is-swagger.yml', 'bar']), 21 | 'this-is-swagger.yml' 22 | )) 23 | 24 | it("detects the first .yaml file containing 'swagger' as OpenAPI 2", () => 25 | assert.equal( 26 | detectApiDescription(['foo', 'this-is-swagger.yaml', 'bar']), 27 | 'this-is-swagger.yaml' 28 | )) 29 | 30 | it("detects the first .yml file containing 'api' as OpenAPI 2", () => 31 | assert.equal( 32 | detectApiDescription(['foo', 'openapi.yml', 'bar']), 33 | 'openapi.yml' 34 | )) 35 | 36 | it("detects the first .yaml file containing 'api' as OpenAPI 2", () => 37 | assert.equal( 38 | detectApiDescription(['foo', 'openapi.yaml', 'bar']), 39 | 'openapi.yaml' 40 | )) 41 | 42 | it('prefers API Blueprint over OpenAPI 2', () => 43 | assert.equal(detectApiDescription(['swagger.yml', 'boo.apib']), 'boo.apib')) 44 | 45 | it("prefers 'swagger' over 'api'", () => 46 | assert.equal( 47 | detectApiDescription(['api.yml', 'swagger.yml']), 48 | 'swagger.yml' 49 | )) 50 | }) 51 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/detectCI-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { detectCI } from '../../../lib/init' 4 | 5 | describe('init._detectCI()', () => { 6 | it('detects no CI on empty array', () => assert.deepEqual(detectCI([]), [])) 7 | 8 | it('detects AppVeyor', () => 9 | assert.deepEqual(detectCI(['README', 'appveyor.yml']), ['appveyor'])) 10 | 11 | it('detects CircleCI', () => 12 | assert.deepEqual(detectCI(['README', '.circleci']), ['circleci'])) 13 | 14 | it('detects Travis CI', () => 15 | assert.deepEqual(detectCI(['README', '.travis.yml']), ['travisci'])) 16 | 17 | it('detects Wercker', () => 18 | assert.deepEqual(detectCI(['README', 'wercker.yml']), ['wercker'])) 19 | 20 | it('detects multiple CIs', () => 21 | assert.deepEqual(detectCI(['README', 'wercker.yml', '.circleci']), [ 22 | 'wercker', 23 | 'circleci' 24 | ])) 25 | }) 26 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/detectLanguage-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { detectLanguage } from '../../../lib/init' 4 | 5 | describe('init._detectLanguage()', () => { 6 | it('defaults to JavaScript', () => assert.equal(detectLanguage([]), 'nodejs')) 7 | ;[ 8 | { name: 'Rust', value: 'rust', file: 'Cargo.toml' }, 9 | { name: 'Go', value: 'go', file: 'foo.go' }, 10 | { name: 'PHP', value: 'php', file: 'composer.json' } 11 | ].forEach(({ name, value, file }) => { 12 | it(`prioritizes ${name} over Python`, () => 13 | assert.equal(detectLanguage(['README', 'Pipfile', file]), value)) 14 | it(`prioritizes ${name} over Ruby`, () => 15 | assert.equal(detectLanguage(['README', 'Gemfile', file]), value)) 16 | }) 17 | 18 | it('detects Python', () => 19 | assert.equal(detectLanguage(['README', 'Pipfile']), 'python')) 20 | it('detects Ruby', () => 21 | assert.equal(detectLanguage(['README', 'Gemfile']), 'ruby')) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/detectServer-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { detectServer } from '../../../lib/init' 4 | 5 | describe('init._detectServer()', () => { 6 | it("defaults to 'npm start' script", () => { 7 | assert.equal(detectServer([]), 'npm start') 8 | }) 9 | 10 | it('assumes Python project means Django application', () => { 11 | assert.equal( 12 | detectServer(['README', 'Pipfile']), 13 | 'python manage.py runserver' 14 | ) 15 | }) 16 | 17 | it('assumes Ruby project means RoR application', () => { 18 | assert.equal( 19 | detectServer(['README', 'Gemfile']), 20 | 'bundle exec rails server' 21 | ) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/printClosingMessage-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { printClosingMessage } from '../../../lib/init' 4 | 5 | function print(s) { 6 | print.output += `${s}\n` 7 | } 8 | 9 | describe('init._printClosingMessage()', () => { 10 | beforeEach(() => { 11 | print.output = '' 12 | }) 13 | 14 | it('mentions the config has been saved to dredd.yml', () => { 15 | printClosingMessage({ language: 'nodejs' }, print) 16 | assert.include(print.output, 'saved to dredd.yml') 17 | }) 18 | it('does not mention hooks when the language is JavaScript', () => { 19 | printClosingMessage({ language: 'nodejs' }, print) 20 | assert.notInclude(print.output, 'hooks') 21 | }) 22 | it('does mention hooks when the language is not JavaScript', () => { 23 | printClosingMessage({ language: 'python' }, print) 24 | assert.include(print.output, 'hooks') 25 | }) 26 | it('hints how to install non-JavaScript hooks', () => { 27 | printClosingMessage({ language: 'python' }, print) 28 | assert.include(print.output, 'pip install dredd_hooks') 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/updateAppVeyor-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { updateAppVeyor } from '../../../lib/init' 4 | 5 | function createOptions(contents) { 6 | return { editYaml: (file, update) => update(contents) } 7 | } 8 | 9 | describe('init._updateAppVeyor()', () => { 10 | it('is able to create a new config file', () => { 11 | const contents = {} 12 | updateAppVeyor(createOptions(contents)) 13 | 14 | assert.include(JSON.stringify(contents), 'dredd') 15 | }) 16 | 17 | it('adds commands to install Dredd', () => { 18 | const contents = { install: ['pipenv install'] } 19 | updateAppVeyor(createOptions(contents)) 20 | 21 | assert.equal(contents.install.length, 4) 22 | assert.match(contents.install[3], /npm.+i.+dredd/) 23 | }) 24 | 25 | it('adds a command to run Dredd', () => { 26 | const contents = { test_script: ['pytest'] } 27 | updateAppVeyor(createOptions(contents)) 28 | 29 | assert.deepEqual(contents.test_script, ['pytest', 'dredd']) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/updateCircleCI-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { updateCircleCI } from '../../../lib/init' 4 | 5 | function createOptions(contents) { 6 | return { editYaml: (file, update) => update(contents) } 7 | } 8 | 9 | describe('init._updateCircleCI()', () => { 10 | it('is able to create a new config file', () => { 11 | const contents = {} 12 | updateCircleCI(createOptions(contents)) 13 | 14 | assert.include(JSON.stringify(contents), 'dredd') 15 | }) 16 | 17 | it("sets a 'dredd' job", () => { 18 | const contents = {} 19 | updateCircleCI(createOptions(contents)) 20 | 21 | assert.match(contents.jobs.dredd.docker[0].image, /\/node:/) 22 | assert.equal(contents.jobs.dredd.steps[0], 'checkout') 23 | assert.match(contents.jobs.dredd.steps[1].run, /npm.+i.+dredd/) 24 | assert.equal(contents.jobs.dredd.steps[2].run, 'dredd') 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/updateTravisCI-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { updateTravisCI } from '../../../lib/init' 4 | 5 | function createOptions(contents) { 6 | return { editYaml: (file, update) => update(contents) } 7 | } 8 | 9 | describe('init._updateTravisCI()', () => { 10 | it('is able to create a new config file', () => { 11 | const contents = {} 12 | updateTravisCI(createOptions(contents)) 13 | 14 | assert.include(JSON.stringify(contents), 'dredd') 15 | }) 16 | 17 | it('adds a command to install Dredd', () => { 18 | const contents = { before_install: ['pipenv install'] } 19 | updateTravisCI(createOptions(contents)) 20 | 21 | assert.equal(contents.before_install[0], 'pipenv install') 22 | assert.match(contents.before_install[1], /npm.+i.+dredd/) 23 | assert.equal(contents.before_install.length, 2) 24 | }) 25 | 26 | it('adds a command to run Dredd', () => { 27 | const contents = { before_script: ['pytest'] } 28 | updateTravisCI(createOptions(contents)) 29 | 30 | assert.deepEqual(contents.before_script, ['pytest', 'dredd']) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/init/updateWercker-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { updateWercker } from '../../../lib/init' 4 | 5 | function createOptions(contents) { 6 | return { editYaml: (file, update) => update(contents) } 7 | } 8 | 9 | describe('init._updateWercker()', () => { 10 | it('is able to create a new config file', () => { 11 | const contents = {} 12 | updateWercker(createOptions(contents)) 13 | 14 | assert.include(JSON.stringify(contents), 'dredd') 15 | }) 16 | 17 | it('adds commands to install and run Dredd', () => { 18 | const contents = { 19 | build: { 20 | steps: [{ script: { name: 'pipenv-install', code: 'pipenv install' } }] 21 | } 22 | } 23 | updateWercker(createOptions(contents)) 24 | 25 | assert.equal(contents.build.steps.length, 3) 26 | assert.match(contents.build.steps[0].script.code, /npm.+i.+dredd/) 27 | assert.equal(contents.build.steps[1].script.code, 'pipenv install') 28 | assert.equal(contents.build.steps[2].script.code, 'dredd') 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/isURL-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | 3 | import isURL from '../../lib/isURL'; 4 | 5 | describe('isURL()', () => { 6 | it('recognizes HTTP URL', () => { 7 | assert.isTrue(isURL('http://example.com')); 8 | }); 9 | 10 | it('recognizes HTTPS URL', () => { 11 | assert.isTrue(isURL('https://example.com')); 12 | }); 13 | 14 | it('returns false for UNIX paths', () => { 15 | assert.isFalse(isURL('/home/honza')); 16 | }); 17 | 18 | it('returns false for Windows paths', () => { 19 | assert.isFalse(isURL('C:\\Users\\Honza')); 20 | }); 21 | 22 | it('returns false for file://', () => { 23 | assert.isFalse(isURL('file:///home/honza')); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/performRequest/createTransactionResponse-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { createTransactionResponse } from '../../../lib/performRequest' 4 | 5 | describe('performRequest._createTransactionResponse()', () => { 6 | const res = { statusCode: 200, headers: {} } 7 | 8 | it('sets the status code', () => 9 | assert.deepEqual(createTransactionResponse(res), { 10 | statusCode: 200, 11 | headers: {} 12 | })) 13 | it('copies the headers', () => { 14 | const headers = { 'Content-Type': 'application/json' } 15 | const transactionRes = createTransactionResponse({ 16 | statusCode: 200, 17 | headers 18 | }) 19 | headers['X-Header'] = 'abcd' 20 | 21 | assert.deepEqual(transactionRes, { 22 | statusCode: 200, 23 | headers: { 'Content-Type': 'application/json' } 24 | }) 25 | }) 26 | it('does not set empty body', () => 27 | assert.deepEqual(createTransactionResponse(res, Buffer.from([])), { 28 | statusCode: 200, 29 | headers: {} 30 | })) 31 | it('sets textual body as a string with UTF-8 encoding', () => 32 | assert.deepEqual(createTransactionResponse(res, Buffer.from('řeřicha')), { 33 | statusCode: 200, 34 | headers: {}, 35 | body: 'řeřicha', 36 | bodyEncoding: 'utf-8' 37 | })) 38 | it('sets binary body as a string with Base64 encoding', () => 39 | assert.deepEqual( 40 | createTransactionResponse(res, Buffer.from([0xff, 0xbe])), 41 | { 42 | statusCode: 200, 43 | headers: {}, 44 | body: Buffer.from([0xff, 0xbe]).toString('base64'), 45 | bodyEncoding: 'base64' 46 | } 47 | )) 48 | }) 49 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/performRequest/detectBodyEncoding-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { detectBodyEncoding } from '../../../lib/performRequest' 4 | 5 | describe('performRequest._detectBodyEncoding()', () => { 6 | it('detects binary content as Base64', () => 7 | assert.equal( 8 | detectBodyEncoding(Buffer.from([0xff, 0xef, 0xbf, 0xbe])), 9 | 'base64' 10 | )) 11 | it('detects textual content as UTF-8', () => 12 | assert.equal(detectBodyEncoding(Buffer.from('řeřicha')), 'utf-8')) 13 | it('detects no content as UTF-8', () => 14 | assert.equal(detectBodyEncoding(Buffer.from([])), 'utf-8')) 15 | }) 16 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/performRequest/getBodyAsBuffer-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { getBodyAsBuffer } from '../../../lib/performRequest' 4 | 5 | describe('performRequest._getBodyAsBuffer()', () => { 6 | describe('when the body is a Buffer', () => { 7 | it('returns the body unmodified', () => { 8 | const body = Buffer.from([0xff, 0xef, 0xbf, 0xbe]) 9 | assert.equal(getBodyAsBuffer(body), body) 10 | }) 11 | it('ignores encoding', () => { 12 | const body = Buffer.from([0xff, 0xef, 0xbf, 0xbe]) 13 | assert.equal(getBodyAsBuffer(body, 'utf-8'), body) 14 | }) 15 | }) 16 | ;[undefined, null, ''].forEach((body) => { 17 | describe(`when the body is ${JSON.stringify(body)}`, () => { 18 | it('returns empty Buffer without encoding', () => 19 | assert.deepEqual(getBodyAsBuffer(body), Buffer.from([]))) 20 | it('returns empty Buffer with encoding set to UTF-8', () => 21 | assert.deepEqual(getBodyAsBuffer(body, 'utf-8'), Buffer.from([]))) 22 | it('returns empty Buffer with encoding set to Base64', () => 23 | assert.deepEqual(getBodyAsBuffer(body, 'base64'), Buffer.from([]))) 24 | }) 25 | }) 26 | 27 | describe('when the body is neither Buffer or string', () => { 28 | it('gracefully stringifies the input', () => { 29 | const body = new Error('Ouch!') 30 | assert.deepEqual(getBodyAsBuffer(body), Buffer.from('Error: Ouch!')) 31 | }) 32 | }) 33 | 34 | describe('when the body is a string', () => { 35 | it('assumes UTF-8 without encoding', () => 36 | assert.deepEqual(getBodyAsBuffer('abc'), Buffer.from('abc'))) 37 | it('respects encoding set to UTF-8', () => 38 | assert.deepEqual(getBodyAsBuffer('abc', 'utf-8'), Buffer.from('abc'))) 39 | it('respects encoding set to Base64', () => { 40 | const body = Buffer.from('abc').toString('base64') 41 | assert.deepEqual(getBodyAsBuffer(body, 'base64'), Buffer.from('abc')) 42 | }) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/performRequest/normalizeBodyEncoding-test.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai' 2 | 3 | import { normalizeBodyEncoding } from '../../../lib/performRequest' 4 | 5 | describe('performRequest._normalizeBodyEncoding()', () => { 6 | ;['utf-8', 'utf8', 'UTF-8', 'UTF8'].forEach((value) => 7 | it(`normalizes ${JSON.stringify(value)} to utf-8`, () => 8 | assert.equal(normalizeBodyEncoding(value), 'utf-8')) 9 | ) 10 | ;['base64', 'Base64'].forEach((value) => 11 | it(`normalizes ${JSON.stringify(value)} to base64`, () => 12 | assert.equal(normalizeBodyEncoding(value), 'base64')) 13 | ) 14 | ;[undefined, null, '', false].forEach((value) => 15 | it(`defaults ${JSON.stringify(value)} to utf-8`, () => 16 | assert.equal(normalizeBodyEncoding(value), 'utf-8')) 17 | ) 18 | it('throws an error on "latin2"', () => 19 | assert.throws(() => { 20 | normalizeBodyEncoding('latin2') 21 | }, /^unsupported encoding/i)) 22 | }) 23 | -------------------------------------------------------------------------------- /packages/dredd/test/unit/resolveModule-test.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { assert } from 'chai'; 3 | 4 | import resolveModule from '../../lib/resolveModule'; 5 | 6 | describe('resolveModule()', () => { 7 | const workingDirectory = path.join(__dirname, '..', 'fixtures'); 8 | 9 | it('resolves a local module name', () => { 10 | assert.equal( 11 | resolveModule(workingDirectory, 'requiredModule'), 12 | path.join(workingDirectory, 'requiredModule'), 13 | ); 14 | }); 15 | 16 | it('resolves a local module name with .js extension', () => { 17 | assert.equal( 18 | resolveModule(workingDirectory, 'requiredModule.js'), 19 | path.join(workingDirectory, 'requiredModule.js'), 20 | ); 21 | }); 22 | 23 | it('resolves an installed module name', () => { 24 | assert.equal( 25 | resolveModule(workingDirectory, 'coffeescript/register'), 26 | 'coffeescript/register', 27 | ); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/dredd/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "es2017", 6 | "lib": ["es2017"], 7 | "typeRoots": ["node_modules/@types"], 8 | "rootDir": "./lib", 9 | "outDir": "./build", 10 | "moduleResolution": "node", 11 | "esModuleInterop": true, 12 | "allowJs": true, 13 | "allowSyntheticDefaultImports": true 14 | }, 15 | "include": ["./lib/**/*.ts", "./lib/**/*.js"], 16 | "exclude": ["node_modules", "build"] 17 | } 18 | -------------------------------------------------------------------------------- /scripts/commitlint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Validates format of the commit messages on CI 3 | 4 | 5 | set -e # aborts as soon as anything returns non-zero exit status 6 | 7 | npx commitlint --from=master 8 | --------------------------------------------------------------------------------