Produced by Araxis Merge on 10/4/2017 8:04:33 AM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
| # | Location | File | Last Modified |
|---|---|---|---|
| 1 | rdk.zip\rdk\product\production\rdk\src\core\api-blueprint | check-api-blueprint-docs-spec.js | Mon Aug 21 12:51:00 2017 UTC |
| 2 | rdk.zip\rdk\product\production\rdk\src\core\api-blueprint | check-api-blueprint-docs-spec.js | Tue Oct 3 17:13:22 2017 UTC |
| Description | Between Files 1 and 2 |
|
|---|---|---|
| Text Blocks | Lines | |
| Unchanged | 2 | 494 |
| Changed | 1 | 2 |
| Inserted | 0 | 0 |
| Removed | 0 | 0 |
| Whitespace | |
|---|---|
| Character case | Differences in character case are significant |
| Line endings | Differences in line endings (CR and LF characters) are ignored |
| CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
| 1 | 'use stric t'; | |
| 2 | ||
| 3 | var fs = r equire('fs '); | |
| 4 | var fspath = require ('path'); | |
| 5 | var _ = re quire('lod ash'); | |
| 6 | var ajv = require('a jv')(); | |
| 7 | var apidoc = require ('apidoc-c ore'); | |
| 8 | var loadRe sources = require('. ./../utils /test-reso urces-load er-spec-he lper'); | |
| 9 | var buildD escription = loadRes ources.bui ldDescript ion; | |
| 10 | var apiBlu eprint = r equire('./ api-bluepr int'); | |
| 11 | ||
| 12 | var ignore Warnings = { | |
| 13 | // par t of a reg ular expre ssion mist aken as a transclude : | |
| 14 | '/fhir /communica tionreques t': [{ mes sage: 'Tra nsclude Er ror: File (\\\\.[0-9 ]+) not fo und.' }], | |
| 15 | // use s an in-pr ogress fea ture of AP I Blueprin t (see htt ps://githu b.com/apia ryio/api-b lueprint/i ssues/58) | |
| 16 | '/labS upportData ': [{ mess age: 'igno ring unrec ognized bl ock' }, { message: ' empty requ est messag e-body' }] | |
| 17 | }; | |
| 18 | var requir eExamples = false; | |
| 19 | ||
| 20 | describe(' API Bluepr int docume ntation,', function( ) { | |
| 21 | ||
| 22 | var re sources = loadResour ces(); | |
| 23 | ||
| 24 | var fi lePaths = _.keys(res ources).so rt(); | |
| 25 | _.each (filePaths , function (filePath ) { | |
| 26 | ||
| 27 | va r apiDocEr rors = []; | |
| 28 | ap idoc.setLo gger({ | |
| 29 | debug: f unction () { }, | |
| 30 | verbose: function () { }, | |
| 31 | info: fu nction () { }, | |
| 32 | warn: fu nction () { }, | |
| 33 | error: f unction (e rror, loca tion) { | |
| 34 | apiD ocErrors.p ush({ erro r: error, location: location } ); | |
| 35 | } | |
| 36 | }) ; | |
| 37 | va r apidocs = apidoc.p arse({ src : fspath.d irname(fil ePath) }); | |
| 38 | if (_.isObje ct(apidocs )) { | |
| 39 | apidocs = JSON.par se(apidocs .data); | |
| 40 | } | |
| 41 | ||
| 42 | va r resource Configs = resources[ filePath]; | |
| 43 | _. each(resou rceConfigs , function (resource ) { | |
| 44 | if (reso urce.undoc umented) { | |
| 45 | retu rn; | |
| 46 | } | |
| 47 | ||
| 48 | var meth od = getMe thod(resou rce); | |
| 49 | var moun tpoint = r esource.mo untpoint.l ength > 1 ? resource .mountpoin t : resour ce.path; | |
| 50 | var mark downPath = getMarkdo wnPath(res ource, fil ePath); | |
| 51 | ||
| 52 | describe (buildDesc ription(re source, re sourceConf igs, fileP ath, metho d), functi on () { | |
| 53 | ||
| 54 | befo re(functio n(done) { | |
| 55 | this.timeo ut(120000) ; | |
| 56 | ||
| 57 | apiBluepri nt.jsonDoc umentation FromFile(m arkdownPat h, mountpo int, funct ion (error , json) { | |
| 58 | resour ce.jsonDoc umentation = json; | |
| 59 | resour ce.actionD ocumentati on = apiBl ueprint.ma tchAction( json, reso urce.path, method); | |
| 60 | done() ; | |
| 61 | }); | |
| 62 | }); | |
| 63 | ||
| 64 | it(' must have an API Blu eprint doc umentation file', fu nction (do ne) { | |
| 65 | fs.stat(ma rkdownPath , function (error, s tats) { | |
| 66 | expect(sta ts, 'Pleas e write AP I Blueprin t document ation for ' + filePa th + '\nSe e instruct ions at ht tps:// IP /documenta tion/#/rdk /documenti ng').to.no t.be.undef ined(); | |
| 67 | done() ; | |
| 68 | }); | |
| 69 | }); | |
| 70 | ||
| 71 | it(' must docum ent the ' + resource .path + ' path', fun ction () { | |
| 72 | expect(res ource.acti onDocument ation, 'Pl ease docum ent the ' + resource .path + ' path').to. not.be.und efined(); | |
| 73 | }); | |
| 74 | ||
| 75 | it(' must have no parse w arnings', function ( ) { | |
| 76 | this.timeo ut(10000); | |
| 77 | ||
| 78 | if (!resou rce.jsonDo cumentatio n) { | |
| 79 | return ; | |
| 80 | } | |
| 81 | ||
| 82 | var actual Warnings = resource. jsonDocume ntation.wa rnings; | |
| 83 | if (ignore Warnings[m ountpoint] ) { | |
| 84 | actual Warnings = _.reject( resource.j sonDocumen tation.war nings, fun ction (war ning) { | |
| 85 | re turn _.fin d(ignoreWa rnings[mou ntpoint], function ( ignoreWarn ing) { | |
| 86 | return _ .isMatch(w arning, ig noreWarnin g); | |
| 87 | }) ; | |
| 88 | }); | |
| 89 | } | |
| 90 | ||
| 91 | expect(act ualWarning s).to.be.e mpty(); | |
| 92 | }); | |
| 93 | ||
| 94 | it(' must have valid exam ples', fun ction () { | |
| 95 | this.timeo ut(10000); | |
| 96 | ||
| 97 | if (!resou rce.action Documentat ion) { | |
| 98 | return ; | |
| 99 | } | |
| 100 | ||
| 101 | _.each(res ource.acti onDocument ation.exam ples, func tion (exam ple) { | |
| 102 | var re quests = _ .map(examp le.request s, withTyp e.bind(nul l, 'reques t')); | |
| 103 | var re sponses = _.map(exam ple.respon ses, withT ype.bind(n ull, 'resp onse')); | |
| 104 | ||
| 105 | _.each (requests. concat(res ponses), f unction (i tem) { | |
| 106 | if (!item.ex ample.body || !item. example.sc hema) { | |
| 107 | var cont entType = (_.find(it em.example .headers, function ( header) { | |
| 108 | retu rn header. name === ' Content-Ty pe'; | |
| 109 | }) || {} ).value; | |
| 110 | if (cont entType && _.contain s(contentT ype, 'json ')) { | |
| 111 | if ( requireExa mples) { | |
| 112 | expect(ite m.example. body, 'Ple ase write an example JSON ' + item.type + ' body') .to.not.be .empty(); | |
| 113 | expect(ite m.example. schema, 'P lease writ e a schema for the ' + item.ty pe + ' bod y').to.not .be.empty( ); | |
| 114 | } el se { | |
| 115 | if (!item. example.bo dy) { | |
| 116 | consol e.log('Ple ase write an example JSON ' + item.type + ' body') ; | |
| 117 | } | |
| 118 | if (!item. example.sc hema) { | |
| 119 | consol e.log('Ple ase write a schema f or the ' + item.type + ' body' ); | |
| 120 | } | |
| 121 | } | |
| 122 | } | |
| 123 | return; | |
| 124 | } | |
| 125 | ||
| 126 | tr y { | |
| 127 | var sche ma = parse Json(item. example.sc hema, item .type + ' schema is not valid JSON'); | |
| 128 | var body = parseJs on(item.ex ample.body , item.typ e + ' is n ot valid J SON'); | |
| 129 | ||
| 130 | var vali d = ajv.va lidate(sch ema, body) ; | |
| 131 | expect(v alid, ajv. errorsText (ajv.error s, { dataV ar: item.t ype })).to .be.true() ; | |
| 132 | } catch (e) { | |
| 133 | deletePr eparsedDoc umentation (markdownP ath); | |
| 134 | throw e; | |
| 135 | } | |
| 136 | }); | |
| 137 | }); | |
| 138 | }); | |
| 139 | ||
| 140 | if ( apiDocErro rs.length) { | |
| 141 | it('must h ave correc t apiDoc d ocumentati on', funct ion () { | |
| 142 | apiDoc Errors.mus t.be.empty (); | |
| 143 | }); | |
| 144 | } | |
| 145 | ||
| 146 | if ( _.isObject (apidocs)) { | |
| 147 | it('must m atch the a piDoc docu mentation' , function () { | |
| 148 | if (!r esource.ac tionDocume ntation) { | |
| 149 | re turn; | |
| 150 | } | |
| 151 | ||
| 152 | var re sourceApi = findApiD ocsForReso urce(resou rce, apido cs, method ); | |
| 153 | if (!r esourceApi ) { | |
| 154 | if (!_.endsW ith(resour ce.path, ' /_search') ) { | |
| 155 | console. log('Warni ng: althou gh the fil e has apiD ocs, there was no en try for ' + resource .path); | |
| 156 | } | |
| 157 | re turn; | |
| 158 | } | |
| 159 | ||
| 160 | var ap iDocParame ters = _.g et(resourc eApi, 'par ameter.fie lds.Parame ter'); | |
| 161 | ||
| 162 | _.each (apiDocPar ameters, f unction (a piDocParam eter) { | |
| 163 | va r blueprin tParameter = _.find( resource.a ctionDocum entation.p arameters, { name: a piDocParam eter.field }); | |
| 164 | ex pect(bluep rintParame ter, 'A `' + apiDocP arameter.f ield + '` parameter is in the apiDocs bu t not in t he API Blu eprint doc umentation ').to.not. be.undefin ed(); | |
| 165 | ex pect(toApi BlueprintT ype(apiDoc Parameter. type), 'th e `' + api DocParamet er.field + '` parame ter has di fferent ty pes betwee n apiDocs and API Bl ueprint'). to.be(blue printParam eter.type) ; | |
| 166 | ex pect(apiDo cParameter .optional, 'the `' + apiDocPar ameter.fie ld + '` pa rameter ha s differen t optional ity betwee n apiDocs and API Bl ueprint'). to.be(!blu eprintPara meter.requ ired); | |
| 167 | }); | |
| 168 | ||
| 169 | _.each (resource. actionDocu mentation. parameters , function (blueprin tParameter ) { | |
| 170 | va r apiDocPa rameter = _.find(api DocParamet ers, { fie ld: bluepr intParamet er.name }) ; | |
| 171 | ex pect(apiDo cParameter , 'A `' + blueprintP arameter.n ame + '` p arameter i s in the A PI Bluepri nt documen tation but not in th e apiDocs' ).to.not.b e.undefine d(); | |
| 172 | ex pect(toApi BlueprintT ype(apiDoc Parameter. type), 'th e `' + api DocParamet er.field + '` parame ter has di fferent ty pes betwee n apiDocs and API Bl ueprint'). to.be(blue printParam eter.type) ; | |
| 173 | ex pect(apiDo cParameter .optional, 'the `' + apiDocPar ameter.fie ld + '` pa rameter ha s differen t optional ity betwee n apiDocs and API Bl ueprint'). to.be(!blu eprintPara meter.requ ired); | |
| 174 | }); | |
| 175 | }); | |
| 176 | } | |
| 177 | }); | |
| 178 | }) ; | |
| 179 | }); | |
| 180 | }); | |
| 181 | ||
| 182 | function g etMarkdown Path(resou rce, fileP ath) { | |
| 183 | return resource. apiBluepri ntFile || filePath + '.md'; | |
| 184 | } | |
| 185 | ||
| 186 | function g etMethod(r esource) { | |
| 187 | return _.find([' get', 'pos t', 'put', 'delete'] , function (httpMetho d) { | |
| 188 | re turn _.has (resource, httpMetho d); | |
| 189 | }).toU pperCase() ; | |
| 190 | } | |
| 191 | ||
| 192 | function w ithType(ty pe, item) { | |
| 193 | return { | |
| 194 | ex ample: ite m, | |
| 195 | ty pe: item.n ame + ' ' + type | |
| 196 | }; | |
| 197 | } | |
| 198 | ||
| 199 | function p arseJson(j son, error Message) { | |
| 200 | try { | |
| 201 | re turn JSON. parse(json ); | |
| 202 | } catc h (e) { | |
| 203 | th row new Er ror(errorM essage); | |
| 204 | } | |
| 205 | } | |
| 206 | ||
| 207 | function d eletePrepa rsedDocume ntation(ma rkdownPath ) { | |
| 208 | try { | |
| 209 | fs .unlinkSyn c(apiBluep rint.prepa rsedJsonPa th(markdow nPath)); | |
| 210 | } catc h (e) { } | |
| 211 | } | |
| 212 | ||
| 213 | function f indApiDocs ForResourc e(resource , apidocs, method) { | |
| 214 | return _.find(ap idocs, fun ction (api Item) { | |
| 215 | if (apiItem. type !== m ethod.toLo werCase()) { | |
| 216 | return f alse; | |
| 217 | } | |
| 218 | va r url = ap iItem.url; | |
| 219 | va r queryInd ex = url.i ndexOf('?' ); | |
| 220 | if (queryInd ex > 0) { | |
| 221 | if (url. charAt(que ryIndex - 1) === '[' ) { | |
| 222 | --qu eryIndex; | |
| 223 | } | |
| 224 | url = ur l.substrin g(0, query Index); | |
| 225 | } | |
| 226 | ur l = url.re place(/\{( \w+)\}/g, ':$1'); | |
| 227 | re turn _.end sWith(url, resource. path); | |
| 228 | }); | |
| 229 | } | |
| 230 | ||
| 231 | function t oApiBluepr intType(ap iDocType) { | |
| 232 | switch (apiDocTy pe.toLower Case()) { | |
| 233 | ca se 'string ': | |
| 234 | return ' string'; | |
| 235 | ca se 'number ': | |
| 236 | ca se 'int': | |
| 237 | ca se 'intege r': | |
| 238 | ca se 'long': | |
| 239 | return ' number'; | |
| 240 | ca se 'boolea n': | |
| 241 | return ' boolean'; | |
| 242 | de fault: | |
| 243 | if (_.en dsWith(api DocType, ' []')) { | |
| 244 | retu rn toApiBl ueprintTyp e(apiDocTy pe.substri ng(0, apiD ocType.len gth - 2)); | |
| 245 | } | |
| 246 | return a piDocType; | |
| 247 | } | |
| 248 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.