diff --git a/README.md b/README.md index 7a3d22e..d9f75a3 100644 --- a/README.md +++ b/README.md @@ -48,32 +48,46 @@ Dredd Transactions library is written in JavaScript (ES2015+). ## Usage -### `compile` +### `parse` -Compiles *HTTP Transactions* from given API description document. +Parses given API description document into API Elements with options specific +to Dredd. Assumes that documents with unrecognizable format are +[API Blueprint][api-blueprint]. Turns any parser failures, including +the unexpected ones, into [API Elements][api-elements] annotations. ```javascript -var dt = require('dredd-transactions'); +const parse = require('dredd-transactions/parse'); +// const { parse } = require('dredd-transactions'); -dt.compile('# My API\n...', 'apiary.apib', function (error, compileResult) { +parse('# My API\n...', (error, parseResult) => { // ... }); ``` -### Arguments +### `compile` + +Compiles *HTTP Transactions* from given [API Elements][api-elements]. *HTTP Transactions* are a backbone data structure to Dredd. -- (string) - API description document provided as string. -- (string) - Original file name of the API description document. **To be removed! See [#6][filename-deprecation].** -- (function) - Callback. +```javascript +const compile = require('dredd-transactions/compile'); +// const { compile } = require('dredd-transactions'); -### Callback Arguments +const compileResult = compile(mediaType, apiElements, filename); +``` -- (enum[null, object]) - Standard JavaScript error object. -- ([Compile Result][compile-result-object-spec]) +> **Note:** The `filename` argument is optional and about to get deprecated, see [#6][filename-deprecation] ## Data Structures + +### Parse Result (object) + +Result of parsing. + +- `mediaType`: `text/vnd.apiblueprint` (string, default, nullable) - Media type of the input format, can be empty in case of some fatal errors +- `apiElements` ([API Elements][api-elements]) - API Elements parse result + ### Compile Result (object) @@ -161,9 +175,10 @@ Description of an error or warning which occurred during parsing of the API desc > **Note:** These properties are to be superseded by whatever comes out of the proposal in [apiaryio/dredd#227](https://github.com/apiaryio/dredd/issues/227). -[dredd]: https://github.com/apiaryio/dredd +[dredd]: https://dredd.org [mson-spec]: https://github.com/apiaryio/mson [api-elements]: http://api-elements.readthedocs.org/ +[api-blueprint]: https://apiblueprint.org/ [api-blueprint-glossary]: https://github.com/apiaryio/api-blueprint/blob/master/Glossary%20of%20Terms.md [blueprint-transactions]: https://github.com/apiaryio/blueprint-transactions/ diff --git a/lib/compileTransactionName.js b/lib/compile/compileTransactionName.js similarity index 100% rename from lib/compileTransactionName.js rename to lib/compile/compileTransactionName.js diff --git a/lib/compileURI/compileParams.js b/lib/compile/compileURI/compileParams.js similarity index 100% rename from lib/compileURI/compileParams.js rename to lib/compile/compileURI/compileParams.js diff --git a/lib/compileURI/expandURItemplate.js b/lib/compile/compileURI/expandURItemplate.js similarity index 100% rename from lib/compileURI/expandURItemplate.js rename to lib/compile/compileURI/expandURItemplate.js diff --git a/lib/compileURI/index.js b/lib/compile/compileURI/index.js similarity index 100% rename from lib/compileURI/index.js rename to lib/compile/compileURI/index.js diff --git a/lib/compileURI/validateParams.js b/lib/compile/compileURI/validateParams.js similarity index 100% rename from lib/compileURI/validateParams.js rename to lib/compile/compileURI/validateParams.js diff --git a/lib/detectTransactionExampleNumbers.js b/lib/compile/detectTransactionExampleNumbers.js similarity index 100% rename from lib/detectTransactionExampleNumbers.js rename to lib/compile/detectTransactionExampleNumbers.js diff --git a/lib/compile.js b/lib/compile/index.js similarity index 100% rename from lib/compile.js rename to lib/compile/index.js diff --git a/lib/index.js b/lib/index.js index 3833380..7517d9f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,25 +1,5 @@ const parse = require('./parse'); -const compileFromApiElements = require('./compile'); +const compile = require('./compile'); -function compile(apiDescription, filename, callback) { - parse(apiDescription, (err, parseResult) => { - // Shouldn't happen, 'parse' turns all parser crashes into annotations - if (err) { callback(err); return; } - - // Should always set annotations and never throw, try/catch deals only - // with unexpected compiler crashes - let compileResult; - try { - const { mediaType, apiElements } = parseResult; - compileResult = compileFromApiElements(mediaType, apiElements, filename); - } catch (syncErr) { - callback(syncErr); - return; - } - callback(null, compileResult); - }); -} - - -module.exports = { compile }; +module.exports = { compile, parse }; diff --git a/scripts/smoke.sh b/scripts/smoke.sh index e2ecbcd..11072f4 100755 --- a/scripts/smoke.sh +++ b/scripts/smoke.sh @@ -56,10 +56,29 @@ if [ ! -z "$TRAVIS" ]; then "The packaging of Dredd Transactions should have prevented this." echo "======================================================================" exit 1 - else - echo "SUCCESS" - echo "======================================================================" fi + + echo "Importing dredd-transactions" + echo "======================================================================" + echo "const assert = require('assert');" > index.js + echo "const dt = require('dredd-transactions');" >> index.js + echo "assert.ok(typeof dt.parse === 'function');" >> index.js + echo "assert.ok(typeof dt.compile === 'function');" >> index.js + node index.js + + echo "======================================================================" + echo "Importing dredd-transactions/parse and dredd-transactions/compile" + echo "======================================================================" + echo "const assert = require('assert');" > index.js + echo "const parse = require('dredd-transactions/parse');" >> index.js + echo "const compile = require('dredd-transactions/compile');" >> index.js + echo "assert.ok(typeof parse === 'function');" >> index.js + echo "assert.ok(typeof compile === 'function');" >> index.js + node index.js + + echo "======================================================================" + echo "SUCCESS" + echo "======================================================================" else exit 1 fi diff --git a/test/integration/compile-test.js b/test/integration/compile-test.js index a48be1b..437252f 100644 --- a/test/integration/compile-test.js +++ b/test/integration/compile-test.js @@ -147,7 +147,7 @@ describe('compile() · all API description formats', () => { fixtures('ordinary').forEachDescribe(({ mediaType, apiElements }) => { const message = '... dummy warning message ...'; const stubbedCompile = proxyquire('../../lib/compile', { - './compileURI': proxyquire('../../lib/compileURI', { + './compileURI': proxyquire('../../lib/compile/compileURI', { './expandURItemplate': () => ({ uri: '/honey?beekeeper=Honza', errors: [], warnings: [message] }), }), }); @@ -208,7 +208,7 @@ describe('compile() · all API description formats', () => { fixtures('ordinary').forEachDescribe(({ mediaType, apiElements }) => { const message = '... dummy warning message ...'; const stubbedCompile = proxyquire('../../lib/compile', { - './compileURI': proxyquire('../../lib/compileURI', { + './compileURI': proxyquire('../../lib/compile/compileURI', { './validateParams': () => ({ errors: [], warnings: [message] }), }), }); diff --git a/test/integration/compileAPIB-test.js b/test/integration/compileAPIB-test.js index 6695683..250830e 100644 --- a/test/integration/compileAPIB-test.js +++ b/test/integration/compileAPIB-test.js @@ -3,7 +3,7 @@ const proxyquire = require('proxyquire').noPreserveCache(); const createAnnotationSchema = require('../schemas/createAnnotationSchema'); const createCompileResultSchema = require('../schemas/createCompileResultSchema'); -const detectTransactionExampleNumbers = require('../../lib/detectTransactionExampleNumbers'); +const detectTransactionExampleNumbers = require('../../lib/compile/detectTransactionExampleNumbers'); const { assert, fixtures } = require('../support'); const compile = require('../../lib/compile'); diff --git a/test/integration/compileOpenAPI2-test.js b/test/integration/compileOpenAPI2-test.js index b2d4b54..a538b98 100644 --- a/test/integration/compileOpenAPI2-test.js +++ b/test/integration/compileOpenAPI2-test.js @@ -3,7 +3,7 @@ const proxyquire = require('proxyquire'); const createAnnotationSchema = require('../schemas/createAnnotationSchema'); const createCompileResultSchema = require('../schemas/createCompileResultSchema'); -const detectTransactionExampleNumbers = require('../../lib/detectTransactionExampleNumbers'); +const detectTransactionExampleNumbers = require('../../lib/compile/detectTransactionExampleNumbers'); const { assert, fixtures } = require('../support'); const compile = require('../../lib/compile'); diff --git a/test/integration/dreddTransactions-test.js b/test/integration/dreddTransactions-test.js deleted file mode 100644 index a9ab9a0..0000000 --- a/test/integration/dreddTransactions-test.js +++ /dev/null @@ -1,212 +0,0 @@ -const proxyquire = require('proxyquire').noPreserveCache(); - -const createCompileResultSchema = require('../schemas/createCompileResultSchema'); -const createAnnotationSchema = require('../schemas/createAnnotationSchema'); -const dreddTransactions = require('../../lib/index'); - -const { assert, fixtures } = require('../support'); - - -describe('Dredd Transactions', () => { - describe('when compilation throws an exception', () => { - const error = new Error('... dummy message ...'); - let err; - let compileResult; - - beforeEach((done) => { - const stubbedDreddTransactions = proxyquire('../../lib/index', { - './compile': () => { throw error; }, - }); - stubbedDreddTransactions.compile('... dummy API description document ...', null, (...args) => { - [err, compileResult] = args; - done(); - }); - }); - - it('passes the error to callback', () => { - assert.equal(err, error); - }); - it('passes no compile result to callback', () => { - assert.isUndefined(compileResult); - }); - }); - - describe('when given empty API description document', () => { - let compileResult; - - beforeEach((done) => { - dreddTransactions.compile('', null, (err, result) => { - compileResult = result; - done(err); - }); - }); - - it('produces one annotation, no transactions', () => { - assert.jsonSchema(compileResult, createCompileResultSchema({ - annotations: 1, - transactions: 0, - })); - }); - it('produces warning about falling back to API Blueprint', () => { - assert.jsonSchema(compileResult.annotations[0], createAnnotationSchema({ - type: 'warning', - component: 'apiDescriptionParser', - message: 'assuming API Blueprint', - })); - }); - }); - - describe('when given unknown API description format', () => { - const apiDescription = '... unknown API description format ...'; - let compileResult; - - beforeEach((done) => { - dreddTransactions.compile(apiDescription, null, (err, result) => { - compileResult = result; - done(err); - }); - }); - - it('produces two annotations, no transactions', () => { - assert.jsonSchema(compileResult, createCompileResultSchema({ - annotations: 2, - transactions: 0, - })); - }); - it('produces warning about falling back to API Blueprint', () => { - assert.jsonSchema(compileResult.annotations[0], createAnnotationSchema({ - type: 'warning', - component: 'apiDescriptionParser', - message: 'assuming API Blueprint', - })); - }); - it('produces a warning about the API Blueprint not being valid', () => { - assert.jsonSchema(compileResult.annotations[1], createAnnotationSchema({ - type: 'warning', - component: 'apiDescriptionParser', - message: 'expected', - })); - }); - }); - - describe('when given unrecognizable API Blueprint format', () => { - let compileResult; - const { apiDescription } = fixtures('unrecognizable').apib; - - beforeEach((done) => { - dreddTransactions.compile(apiDescription, null, (err, result) => { - compileResult = result; - done(err); - }); - }); - - it('produces one annotation', () => { - assert.jsonSchema(compileResult, createCompileResultSchema({ - annotations: 1, - transactions: 0, - })); - }); - it('produces no errors', () => { - const errors = compileResult.annotations.filter(annotation => annotation.type === 'error'); - assert.deepEqual(errors, []); - }); - it('produces a warning about falling back to API Blueprint', () => { - assert.jsonSchema(compileResult.annotations[0], createAnnotationSchema({ - type: 'warning', - component: 'apiDescriptionParser', - message: 'assuming API Blueprint', - })); - }); - }); - - describe('when given API description with errors', () => { - fixtures('parser-error').forEachDescribe(({ apiDescription }) => { - let compileResult; - - beforeEach((done) => { - dreddTransactions.compile(apiDescription, null, (err, result) => { - compileResult = result; - done(err); - }); - }); - - it('produces some annotations, no transactions', () => { - assert.jsonSchema(compileResult, createCompileResultSchema({ - annotations: [1], - transactions: 0, - })); - }); - it('produces errors', () => { - assert.jsonSchema(compileResult.annotations, { - type: 'array', - items: createAnnotationSchema({ type: 'error' }), - }); - }); - }); - }); - - describe('when given API description with warnings', () => { - fixtures('parser-warning').forEachDescribe(({ apiDescription }) => { - let compileResult; - - beforeEach((done) => { - dreddTransactions.compile(apiDescription, null, (err, result) => { - compileResult = result; - done(err); - }); - }); - - it('produces some annotations', () => { - assert.jsonSchema(compileResult, createCompileResultSchema({ - annotations: [1], - })); - }); - it('produces warnings', () => { - assert.jsonSchema(compileResult.annotations, { - type: 'array', - items: createAnnotationSchema({ type: 'warning' }), - }); - }); - }); - }); - - describe('when given valid API description', () => { - fixtures('ordinary').forEachDescribe(({ apiDescription }) => { - let compileResult; - - beforeEach((done) => { - dreddTransactions.compile(apiDescription, null, (err, result) => { - compileResult = result; - done(err); - }); - }); - - it('produces no annotations and some transactions', () => { - assert.jsonSchema(compileResult, createCompileResultSchema()); - }); - }); - }); - - describe('when parser unexpectedly provides an error', () => { - const error = new Error('... dummy message ...'); - let err; - let compileResult; - - beforeEach((done) => { - const stubbedDreddTransactions = proxyquire('../../lib/index', { - './parse': (apiDescription, callback) => callback(error), - }); - stubbedDreddTransactions.compile('... dummy API description document ...', null, (...args) => { - [err, compileResult] = args; - done(); - }); - }); - - it('passes the error to callback', () => { - assert.equal(err, error); - }); - it('passes no compile result to callback', () => { - assert.isUndefined(compileResult); - }); - }); -}); diff --git a/test/unit/compileTransactionName-test.js b/test/unit/compileTransactionName-test.js index 29ce331..14de478 100644 --- a/test/unit/compileTransactionName-test.js +++ b/test/unit/compileTransactionName-test.js @@ -1,6 +1,6 @@ const { assert } = require('chai'); -const compileTransactionName = require('../../lib/compileTransactionName'); +const compileTransactionName = require('../../lib/compile/compileTransactionName'); describe('compileTransactionName()', () => { diff --git a/test/unit/compileURI/compileParams-test.js b/test/unit/compileURI/compileParams-test.js index 31344d1..b10aeec 100644 --- a/test/unit/compileURI/compileParams-test.js +++ b/test/unit/compileURI/compileParams-test.js @@ -1,7 +1,7 @@ const { assert } = require('chai'); const fury = require('fury'); -const compileParams = require('../../../lib/compileURI/compileParams'); +const compileParams = require('../../../lib/compile/compileURI/compileParams'); describe('compileParams()', () => { diff --git a/test/unit/compileURI/expandURItemplate-test.js b/test/unit/compileURI/expandURItemplate-test.js index 579af91..a7cd9f3 100644 --- a/test/unit/compileURI/expandURItemplate-test.js +++ b/test/unit/compileURI/expandURItemplate-test.js @@ -1,6 +1,6 @@ const { assert } = require('chai'); -const expandUriTemplate = require('../../../lib/compileURI/expandURItemplate'); +const expandUriTemplate = require('../../../lib/compile/compileURI/expandURItemplate'); describe('expandUriTemplate()', () => { diff --git a/test/unit/compileURI/validateParams-test.js b/test/unit/compileURI/validateParams-test.js index 6b0a751..5ffd35a 100644 --- a/test/unit/compileURI/validateParams-test.js +++ b/test/unit/compileURI/validateParams-test.js @@ -1,6 +1,6 @@ const { assert } = require('chai'); -const validateParams = require('../../../lib/compileURI/validateParams'); +const validateParams = require('../../../lib/compile/compileURI/validateParams'); describe('validateParams()', () => { diff --git a/test/unit/detectTransactionExampleNumbers-test.js b/test/unit/detectTransactionExampleNumbers-test.js index 7bfb49d..14298e7 100644 --- a/test/unit/detectTransactionExampleNumbers-test.js +++ b/test/unit/detectTransactionExampleNumbers-test.js @@ -1,4 +1,4 @@ -const detectTransactionExampleNumbers = require('../../lib/detectTransactionExampleNumbers'); +const detectTransactionExampleNumbers = require('../../lib/compile/detectTransactionExampleNumbers'); const parse = require('../../lib/parse'); const { assert } = require('../support');