diff --git a/.eslintrc b/.eslintrc index fdacb7f1..4876b92f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,7 +9,8 @@ "globals": { "should": true, "expect": true, - "sinon": true + "sinon": true, + "Reflect": true }, "rules": { "quotes": [2, "single"], diff --git a/.travis.yml b/.travis.yml index 0252e24c..13ded6a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,8 @@ cache: before_install: - travis_retry npm install jspm - jspm config registries.github.auth $JSPM_GITHUB_AUTH_TOKEN +before_script: +- npm run jspm-install before_deploy: - npm run build-dist deploy: @@ -38,12 +40,6 @@ deploy: on: branch: master condition: $JOB != e2e - - skip_cleanup: true - provider: script - script: npm run branch-release - on: - branch: master - condition: $JOB != e2e - provider: npm skip_cleanup: true email: gotsijroman@gmail.com @@ -51,3 +47,9 @@ deploy: secure: PuhWLERrCEFmXmdFpw2OVFlqpOIVDmgwk5JUJOYaFdVCh/smp0+jZCQ4vrdFpuG96rnDVirD+A8xvW6NgsNNaRthLgOB/LRdFN69rU6Gvn3At6wlnC55t5dlhxPvCfnzJcHVBLXX4EmMkjnZqDg2uczXTzPodr3FnQJNuXmP8B33fzDVLyHccvXZ90abwXWVrgRIXPU28niqCR8DOC2OTzs7wqz+BLNkYDRRbyYXsg62HWuD33x5iof5IqBmhzBt3usCGmF3QGcgHrXHdZw3sZnit8+Bua++3KrXR0x6HGXXN1AoXVmCAkCa5OTQ5R3tCRxiJN3P2KLnvWeZR74sTFkovJB/6pGCvbJ/c7Wnuw6sD7SgOUBD359ULB6lAf5OnxBLoNebX4JxxVXF+zA4E3Bl44VxkzDpPWc15xqBPMB5vBREzMVmJ5mExn2s5cmLQjADbl9h0y6gZnhnNJ+iTmqtrVyM0ZkF2rPrzrTdGD+ULmRIlTMkdD1bh+/TJ3RdXT3P4/zNUJmiNnvgnnJVYYvsGaXWF+7uCVHT/8k2RsoSHqgkqh0gkDqGSwVix55y5mC7T2Vk9lMBhm6MvFJXaonOX0kxJS4EDQ3plPd6/ybG+TLhwggYnQ8o9msU5Nt6FpUShKiezjKurIhbQZdwlVivX3tahjW2QjNDO58xGgY= on: tags: true + - skip_cleanup: true + provider: script + script: npm run branch-release + on: + branch: master + condition: $JOB != e2e diff --git a/README.md b/README.md index a460b5e1..c39f95b2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ReDoc -[![Build Status](https://travis-ci.org/Rebilly/ReDoc.svg?branch=master)](https://travis-ci.org/Rebilly/ReDoc) [![Coverage Status](https://coveralls.io/repos/Rebilly/ReDoc/badge.svg?branch=master&service=github)](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [![Code Climate](https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg)](https://codeclimate.com/github/Rebilly/ReDoc) [![David](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) +[![Build Status](https://travis-ci.org/Rebilly/ReDoc.svg?branch=master)](https://travis-ci.org/Rebilly/ReDoc) [![Coverage Status](https://coveralls.io/repos/Rebilly/ReDoc/badge.svg?branch=master&service=github)](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [![Code Climate](https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg)](https://codeclimate.com/github/Rebilly/ReDoc) [![David](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [![Stories in Ready](https://badge.waffle.io/Rebilly/ReDoc.png?label=ready&title=Ready)](https://waffle.io/Rebilly/ReDoc) [![npm](http://img.shields.io/npm/v/redoc.svg)](https://www.npmjs.com/package/swagger-parser) [![Bower](http://img.shields.io/bower/v/redoc.svg)](http://bower.io/) [![License](https://img.shields.io/npm/l/redoc.svg)](https://github.com/Rebilly/ReDoc/blob/master/LICENSE) diff --git a/build/tasks/build.js b/build/tasks/build.js index 2f14a46f..408cea9c 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -42,12 +42,14 @@ gulp.task('inlineTemplates', ['sass'], function() { }); var JS_DEV_DEPS = [ + 'lib/utils/browser-update.js', 'node_modules/zone.js/dist/zone-microtask.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/babel-polyfill/dist/polyfill.js' ]; var JS_DEV_DEPS_MIN = [ + 'lib/utils/browser-update.js', 'node_modules/zone.js/dist/zone-microtask.min.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/babel-polyfill/dist/polyfill.min.js' @@ -91,7 +93,7 @@ function bundle(outputFile, minify, cb) { builder .buildStatic(path.join(paths.tmp, paths.sourceEntryPoint), outputFile, - { format:'umd', sourceMaps: true, lowResSourceMaps: true, minify: minify } + { format:'umd', sourceMaps: true, mangle: false, lowResSourceMaps: true, minify: minify } ) .then(function() { cb(); diff --git a/demo/index.html b/demo/index.html index 1d480d20..c189d992 100644 --- a/demo/index.html +++ b/demo/index.html @@ -17,7 +17,7 @@ - + diff --git a/demo/main.js b/demo/main.js index a7fd542a..836eaa45 100644 --- a/demo/main.js +++ b/demo/main.js @@ -8,4 +8,6 @@ Redoc.init(schemaUrlInput.value); return false; }) + + //window.redocDebugMode = true; })(); diff --git a/karma.conf.js b/karma.conf.js index 537dd917..9d1d480d 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -49,18 +49,19 @@ module.exports = function (config) { 'node_modules/zone.js/dist/long-stack-trace-zone.js', 'node_modules/zone.js/dist/jasmine-patch.js', 'node_modules/babel-polyfill/dist/polyfill.js', - 'node_modules/reflect-metadata/Reflect.js' + './node_modules/reflect-metadata/Reflect.js' ], jspm: { config: 'system.config.js', - loadFiles: ['tests/unit/*.spec.js', 'tests/helpers.js', 'lib/**/*.js'], + loadFiles: ['tests/setup.js', 'tests/helpers.js', 'tests/unit/*.spec.js', 'lib/**/*.js'], serveFiles: ['tests/schemas/**/*.json','tests/schemas/**/*.yml', 'lib/**/*.html', '.tmp/lib/**/*.css'], nocache: true }, proxies: { '/tests/': '/base/tests/', + '/lib/components/Redoc/redoc-loading-styles.css': '/base/.tmp/lib/components/Redoc/redoc-loading-styles.css', '/lib/': '/base/lib/', '/jspm_packages/': '/base/jspm_packages/', '/node_modules/': '/base/node_modules/', diff --git a/lib/common/components/StickySidebar/sticky-sidebar.js b/lib/common/components/StickySidebar/sticky-sidebar.js index ad99a264..701204d1 100644 --- a/lib/common/components/StickySidebar/sticky-sidebar.js +++ b/lib/common/components/StickySidebar/sticky-sidebar.js @@ -7,16 +7,17 @@ import {BrowserDomAdapter} from 'angular2/platform/browser'; selector: '[sticky-sidebar]', inputs: ['scrollParent', 'scrollYOffset'] }) +@Reflect.metadata('parameters', [[ElementRef], [BrowserDomAdapter]]) export default class StickySidebar { constructor(elementRef, dom) { - this.element = elementRef.nativeElement; + this.$element = elementRef.nativeElement; this.dom = dom; // initial styling - this.dom.setStyle(this.element, 'position', 'absolute'); - this.dom.setStyle(this.element, 'top', '0'); - this.dom.setStyle(this.element, 'bottom', '0'); - this.dom.setStyle(this.element, 'max-height', '100%'); + this.dom.setStyle(this.$element, 'position', 'absolute'); + this.dom.setStyle(this.$element, 'top', '0'); + this.dom.setStyle(this.$element, 'bottom', '0'); + this.dom.setStyle(this.$element, 'max-height', '100%'); } bind() { @@ -29,7 +30,7 @@ export default class StickySidebar { } updatePosition() { - if ( this.scrollY + this.scrollYOffset() >= this.redocEl.offsetTop) { + if ( this.scrollY + this.scrollYOffset() >= this.$redocEl.offsetTop) { this.stick(); } else { this.unstick(); @@ -37,13 +38,13 @@ export default class StickySidebar { } stick() { - this.dom.setStyle(this.element, 'position', 'fixed'); - this.dom.setStyle(this.element, 'top', this.scrollYOffset() + 'px'); + this.dom.setStyle(this.$element, 'position', 'fixed'); + this.dom.setStyle(this.$element, 'top', this.scrollYOffset() + 'px'); } unstick() { - this.dom.setStyle(this.element, 'position', 'absolute'); - this.dom.setStyle(this.element, 'top', 0); + this.dom.setStyle(this.$element, 'position', 'absolute'); + this.dom.setStyle(this.$element, 'top', 0); } get scrollY() { @@ -51,7 +52,8 @@ export default class StickySidebar { } ngOnInit() { - this.redocEl = this.element.offsetParent; + // FIXME use more reliable code + this.$redocEl = this.$element.offsetParent; this.bind(); } @@ -59,5 +61,3 @@ export default class StickySidebar { this.unbind(); } } - -StickySidebar.parameters = [ [ElementRef], [BrowserDomAdapter] ]; diff --git a/lib/common/components/Tabs/tabs.js b/lib/common/components/Tabs/tabs.js index 5345f282..44a6e8d9 100644 --- a/lib/common/components/Tabs/tabs.js +++ b/lib/common/components/Tabs/tabs.js @@ -65,16 +65,25 @@ export class Tabs { }) @View({ template: ` -
+
- ` + `, + directives: [CORE_DIRECTIVES], + styles: [` + .tab-wrap { + display: none; + } + + .tab-wrap.active { + display: block; + }` + ] }) +@Reflect.metadata('parameters', [ [Tabs] ]) export class Tab { constructor(tabs) { this.active = false; tabs.addTab(this); } } - -Tab.parameters = [ [ Tabs ] ]; diff --git a/lib/common/components/Zippy/zippy.scss b/lib/common/components/Zippy/zippy.scss index 97958a38..f31e943b 100644 --- a/lib/common/components/Zippy/zippy.scss +++ b/lib/common/components/Zippy/zippy.scss @@ -64,6 +64,7 @@ span.zippy-indicator { } .zippy-hidden { + overflow: hidden; visibility: hidden; height: 0; padding: 0; diff --git a/lib/components/ApiInfo/api-info.spec.js b/lib/components/ApiInfo/api-info.spec.js index d9f9e95f..83abf877 100644 --- a/lib/components/ApiInfo/api-info.spec.js +++ b/lib/components/ApiInfo/api-info.spec.js @@ -56,7 +56,6 @@ describe('Redoc components', () => { @Component({selector: 'test-app'}) @View({ directives: [ApiInfo], - providers: [SchemaManager], template: `` }) diff --git a/lib/components/ApiLogo/api-logo.js b/lib/components/ApiLogo/api-logo.js index a4e086bd..46db79dd 100644 --- a/lib/components/ApiLogo/api-logo.js +++ b/lib/components/ApiLogo/api-logo.js @@ -7,7 +7,7 @@ import {RedocComponent, BaseComponent} from '../base'; styleUrls: ['./lib/components/ApiLogo/api-logo.css'], templateUrl: './lib/components/ApiLogo/api-logo.html' }) -export default class ApiInfo extends BaseComponent { +export default class ApiLogo extends BaseComponent { constructor(schemaMgr) { super(schemaMgr); } diff --git a/lib/components/JsonSchema/json-schema-common.scss b/lib/components/JsonSchema/json-schema-common.scss index 434b63f3..e3e7ce97 100644 --- a/lib/components/JsonSchema/json-schema-common.scss +++ b/lib/components/JsonSchema/json-schema-common.scss @@ -30,8 +30,11 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; } .param-name { + flex-grow: 0; + -ms-flex-grow: 0; + display: inline-block; font-size: 14px; - padding: $cell-padding $cell-spacing $cell-padding 0; + padding: $cell-padding 0 $cell-padding 0; font-weight: bold; box-sizing: border-box; line-height: $param-name-height; @@ -40,15 +43,24 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; position: relative; } +.param-name-content { + padding-right: $cell-spacing; + display: inline-block; +} + .param-info { - width: 100%; + //width: 100%; + flex-grow: 1; + -ms-flex-grow: 1; padding: $cell-padding 0; box-sizing: border-box; border-bottom: 1px solid #ccc; + display: inline-block; } .param { display: flex; + display: -ms-flexbox; } .param-required { @@ -72,11 +84,11 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; color: #999; } -.param-type.string { +.param-type.string, .enum-value.string { color: rgba(0, 80, 0, 0.7); } -.param-type.integer, .param-type.number { +.param-type.integer, .param-type.number, .enum-value.number { color: rgba(74, 139, 179, 0.8); } @@ -84,7 +96,7 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; color: rgba(0, 50, 159, 0.7); } -.param-type.boolean { +.param-type.boolean, .enum-value.boolean { color: firebrick; } @@ -158,3 +170,25 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; .param-schema .param-wrap:first-of-type .param-name:before { display: none !important; } + +.param-enum { + color: #666; + + &:before { + content: "Values: {" + } + + &:after { + content: "}" + } + + > .enum-value { + &:after { + content: ", "; + } + + &:last-of-type:after { + content: none; + } + } +} diff --git a/lib/components/JsonSchema/json-schema-lazy.js b/lib/components/JsonSchema/json-schema-lazy.js index dddfb83b..a8c7b589 100644 --- a/lib/components/JsonSchema/json-schema-lazy.js +++ b/lib/components/JsonSchema/json-schema-lazy.js @@ -2,27 +2,41 @@ import {Component, View, ElementRef} from 'angular2/core'; import {CORE_DIRECTIVES} from 'angular2/common'; -import JsonSchema from './json-schema'; import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader'; + +import JsonSchema from './json-schema'; import OptionsManager from '../../options'; +import SchemaManager from '../../utils/SchemaManager'; + + +var cache = {}; + @Component({ selector: 'json-schema-lazy', - inputs: ['pointer'] + inputs: ['pointer', 'auto'] }) @View({ template: '', directives: [CORE_DIRECTIVES] }) +@Reflect.metadata('parameters', [[SchemaManager], [ElementRef], [DynamicComponentLoader], [OptionsManager]]) export default class JsonSchemaLazy { - constructor(elementRef, dcl) { + constructor(schemaMgr, elementRef, dcl, optionsMgr) { this.elementRef = elementRef; this.dcl = dcl; + this.optionsMgr = optionsMgr; + this.schemaMgr = schemaMgr; + } + + normalizePointer() { + let schema = this.schemaMgr.byPointer(this.pointer); + return schema && schema.$ref || this.pointer; } load() { - if (OptionsManager.instance().options.disableLazySchemas) return; + if (this.optionsMgr.options.disableLazySchemas) return; if (this.loaded) return; if (this.pointer) { this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => { @@ -31,5 +45,46 @@ export default class JsonSchemaLazy { } this.loaded = true; } + + // cache JsonSchema view + loadCached() { + this.pointer = this.normalizePointer(this.pointer); + if (cache[this.pointer]) { + cache[this.pointer].then((compRef) => { + setTimeout( ()=> { + let $element = compRef.location.nativeElement; + + // skip caching view with tabs inside (discriminator) as it needs attached controller + if ($element.querySelector('tabs')) { + this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => { + compRef.instance.pointer = this.pointer; + compRef.hostView.changeDetectorRef.markForCheck(); + }); + return; + } + insertAfter($element.cloneNode(true), this.elementRef.nativeElement); + } ); + }); + } else { + cache[this.pointer] = this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => { + compRef.instance.pointer = this.pointer; + compRef.hostView.changeDetectorRef.markForCheck(); + return compRef; + }); + } + } + + ngAfterViewInit() { + if (!this.auto) return; + this.loadCached(); + } + + ngOnDestroy() { + // clear cache + cache = {}; + } +} + +function insertAfter(newNode, referenceNode) { + referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } -JsonSchemaLazy.parameters = [[ElementRef], [DynamicComponentLoader]]; diff --git a/lib/components/JsonSchema/json-schema-lazy.spec.js b/lib/components/JsonSchema/json-schema-lazy.spec.js index 19691476..65535b52 100644 --- a/lib/components/JsonSchema/json-schema-lazy.spec.js +++ b/lib/components/JsonSchema/json-schema-lazy.spec.js @@ -3,6 +3,7 @@ import { getChildDebugElement } from 'tests/helpers'; import {Component, View, provide} from 'angular2/core'; import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader'; +import {BrowserDomAdapter} from 'angular2/platform/browser'; import { TestComponentBuilder, @@ -14,6 +15,7 @@ import { import JsonSchemaLazy from 'lib/components/JsonSchema/json-schema-lazy'; import SchemaManager from 'lib/utils/SchemaManager'; +import OptionsManager from 'lib/options'; describe('Redoc components', () => { describe('JsonSchemaLazy Component', () => { @@ -26,7 +28,9 @@ describe('Redoc components', () => { instance: {} }; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: schemaMgr}) + provide(SchemaManager, {useValue: schemaMgr}), + provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}), + provide(OptionsManager, {useClass: OptionsManager}) ]); beforeEach(inject([TestComponentBuilder, DynamicComponentLoader], (tcb, dcl) => { builder = tcb; @@ -79,7 +83,6 @@ describe('Redoc components', () => { @Component({selector: 'test-app'}) @View({ directives: [JsonSchemaLazy], - providers: [SchemaManager, DynamicComponentLoader], template: `` }) diff --git a/lib/components/JsonSchema/json-schema.html b/lib/components/JsonSchema/json-schema.html index 298b3943..14cf99ca 100644 --- a/lib/components/JsonSchema/json-schema.html +++ b/lib/components/JsonSchema/json-schema.html @@ -6,13 +6,16 @@
- {{prop._name}} + {{prop._name}}
{{prop._displayType}} {{prop._displayFormat}} - Required + Required +
+ {{enumItem.val | json}} +
This field value determines the exact schema:
diff --git a/lib/components/JsonSchema/json-schema.js b/lib/components/JsonSchema/json-schema.js index 75f723e3..0e8a4009 100644 --- a/lib/components/JsonSchema/json-schema.js +++ b/lib/components/JsonSchema/json-schema.js @@ -1,8 +1,9 @@ 'use strict'; -import {RedocComponent, BaseComponent} from '../base'; -import {Tabs, Tab} from '../../common/components/Tabs/tabs'; import {ElementRef} from 'angular2/core'; + +import {RedocComponent, BaseComponent, SchemaManager} from '../base'; +import {Tabs, Tab} from '../../common/components/Tabs/tabs'; import JsonPointer from '../../utils/JsonPointer'; @RedocComponent({ @@ -12,10 +13,11 @@ import JsonPointer from '../../utils/JsonPointer'; directives: [JsonSchema, Tabs, Tab], inputs: ['isArray', 'final'] }) +@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]]) export default class JsonSchema extends BaseComponent { constructor(schemaMgr, elementRef) { super(schemaMgr); - this.element = elementRef.nativeElement; + this.$element = elementRef.nativeElement; this.final = false; } @@ -71,7 +73,8 @@ export default class JsonSchema extends BaseComponent { let discriminatorFieldIdx = -1; let props = Object.keys(schema.properties).map((prop, idx) => { let propData = schema.properties[prop]; - propData = this.injectPropData(prop, propData, schema); + let propPointer = JsonPointer.join(this.pointer, ['properties', prop]); + propData = JsonSchema.injectPropData(propData, prop, propPointer, this.requiredMap, schema); if (propData.isDiscriminator) discriminatorFieldIdx = idx; return propData; }); @@ -83,32 +86,23 @@ export default class JsonSchema extends BaseComponent { this.data.properties = props; } - adjustNameColumnWidth() { - // TODO handle internal schemes differently - let names = [].slice.call(this.element.querySelectorAll('.param-name')); - let widths = names.map(el => el.offsetWidth); - let maxWidth = Math.max(...widths); - if (!maxWidth) return; - names.forEach(el => { - el.style.minWidth = maxWidth + 'px'; - }); + static injectPropData(propData, propName, propPointer, requiredMap, schema) { + let propEnum; - let discrValues = this.element.querySelector('tabs ul'); - if (discrValues) discrValues.style.paddingLeft = maxWidth + 'px'; - } - - injectPropData(prop, propData, schema) { propData = Object.assign({}, propData); - propData._name = prop; - propData.isRequired = this.requiredMap[prop]; + propData._name = propName; + propData.required = propData.required || (requiredMap && requiredMap[propName]); propData._displayType = propData.type; - propData.isDiscriminator = (schema.discriminator === prop); + propData.isDiscriminator = (schema && schema.discriminator === propName); + propEnum = propData.enum; if (propData.type === 'array') { let itemType = propData.items.type; let itemFormat = propData.items.format; + propEnum = propData.items.enum; if (itemType === 'object' || !itemType) { itemType = propData.items.title || 'object'; - propData._pointer = propData.items._pointer || JsonPointer.join(this.pointer, ['properties', prop, 'items']); + propData._pointer = propData.items._pointer + || JsonPointer.join(propPointer, ['items']); } propData._displayType = `${itemType}`; propData.format = itemFormat; @@ -126,12 +120,38 @@ export default class JsonSchema extends BaseComponent { } if (propData.format) propData._displayFormat = `<${propData.format}>`; + if (propEnum) { + propData.enum = propEnum.map((value) => { + return {val: value, type: typeof value}; + }); + } return propData; } - init() { - setTimeout(() => this.adjustNameColumnWidth()); + ngAfterViewInit() { + // adjust widht only on parent level + let $el = this.$element.parentElement; + while($el && $el.tagName !== 'JSON-SCHEMA' && $el.tagName !== 'REDOC') { + $el = $el.parentElement; + } + if ($el && $el.tagName === 'REDOC' ) { + this.adjustNameColumnWidth(); + } + } + + adjustNameColumnWidth() { + // TODO handle internal schemes differently + + let names = [].slice.call(this.$element.querySelectorAll('.param-name-content')); + let widths = [144];//names.map(el => el.offsetWidth); + let maxWidth = Math.max(...widths); + if (!maxWidth) return; + names.forEach(el => { + el.parentNode.style.minWidth = maxWidth + 'px'; + }); + + let discrValues = this.$element.querySelector('tabs ul'); + if (discrValues) discrValues.style.paddingLeft = maxWidth + 'px'; } } -JsonSchema.parameters = JsonSchema.parameters.concat([[ElementRef]]); diff --git a/lib/components/JsonSchema/json-schema.scss b/lib/components/JsonSchema/json-schema.scss index 50948819..01d4ca51 100644 --- a/lib/components/JsonSchema/json-schema.scss +++ b/lib/components/JsonSchema/json-schema.scss @@ -3,6 +3,10 @@ /* styles for array-schema for array */ $array-marker-font-sz: 12px; $array-marker-line-height: 1.5; +:host { + display: block; +} + .params-wrap.params-array:before, .params-wrap.params-array:after { display: block; font-weight: bold; diff --git a/lib/components/JsonSchema/json-schema.spec.js b/lib/components/JsonSchema/json-schema.spec.js index 17ed7ba2..02e54491 100644 --- a/lib/components/JsonSchema/json-schema.spec.js +++ b/lib/components/JsonSchema/json-schema.spec.js @@ -2,6 +2,7 @@ import { getChildDebugElement } from 'tests/helpers'; import {Component, View, provide} from 'angular2/core'; +import OptionsManager from 'lib/options'; import { TestComponentBuilder, @@ -21,7 +22,8 @@ describe('Redoc components', () => { let schemaMgr = new SchemaManager(); let fixture; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: schemaMgr}) + provide(SchemaManager, {useValue: schemaMgr}), + provide(OptionsManager, {useClass: OptionsManager}) ]); beforeEach(inject([TestComponentBuilder], (tcb) => { builder = tcb; diff --git a/lib/components/Method/method.html b/lib/components/Method/method.html index e677c448..1a428a93 100644 --- a/lib/components/Method/method.html +++ b/lib/components/Method/method.html @@ -1,7 +1,7 @@

- {{data.methodInfo.summary}} + {{data.methodInfo.summary}}

{{data.httpMethod}} diff --git a/lib/components/Method/method.js b/lib/components/Method/method.js index 13aa8178..fdad9d66 100644 --- a/lib/components/Method/method.js +++ b/lib/components/Method/method.js @@ -2,6 +2,7 @@ import {JsonPointer} from '../../utils/JsonPointer'; import {RedocComponent, BaseComponent} from '../base'; + import ParamsList from '../ParamsList/params-list'; import ResponsesList from '../ResponsesList/responses-list'; import ResponsesSamples from '../ResponsesSamples/responses-samples'; @@ -28,6 +29,11 @@ export default class Method extends BaseComponent { this.data.methodInfo = this.componentSchema; this.data.methodInfo.tags = this.filterMainTags(this.data.methodInfo.tags); this.data.bodyParam = this.findBodyParam(); + if (this.componentSchema.operationId) { + this.data.methodAnchor = 'operation/' + this.componentSchema.operationId; + } else { + this.data.methodAnchor = 'tag/' + this.tag + this.pointer; + } } filterMainTags(tags) { diff --git a/lib/components/Method/method.spec.js b/lib/components/Method/method.spec.js index 5385c9c8..9e5aee33 100644 --- a/lib/components/Method/method.spec.js +++ b/lib/components/Method/method.spec.js @@ -2,6 +2,7 @@ import { getChildDebugElement } from 'tests/helpers'; import {Component, View, provide} from 'angular2/core'; +import {BrowserDomAdapter} from 'angular2/platform/browser'; import { TestComponentBuilder, @@ -13,13 +14,16 @@ import { import Method from 'lib/components/Method/method'; import SchemaManager from 'lib/utils/SchemaManager'; +import OptionsManager from 'lib/options'; describe('Redoc components', () => { describe('Method Component', () => { let builder; let component; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: new SchemaManager()}) + provide(SchemaManager, {useValue: new SchemaManager()}), + provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}), + provide(OptionsManager, {useClass: OptionsManager}) ]); beforeEach(injectAsync([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { builder = tcb; diff --git a/lib/components/MethodsList/methods-list.html b/lib/components/MethodsList/methods-list.html index 4532d941..10e0ccf6 100644 --- a/lib/components/MethodsList/methods-list.html +++ b/lib/components/MethodsList/methods-list.html @@ -1,10 +1,10 @@
-

{{tag.name}}

+

{{tag.name}}

+ [attr.tag]="method.tag" [tag]="method.tag" [attr.operation-id]="method.operationId">
diff --git a/lib/components/MethodsList/methods-list.spec.js b/lib/components/MethodsList/methods-list.spec.js index ea1d86c5..50f62689 100644 --- a/lib/components/MethodsList/methods-list.spec.js +++ b/lib/components/MethodsList/methods-list.spec.js @@ -2,6 +2,8 @@ import { getChildDebugElement } from 'tests/helpers'; import {Component, View, provide} from 'angular2/core'; +import OptionsManager from 'lib/options'; +import {BrowserDomAdapter} from 'angular2/platform/browser'; import { TestComponentBuilder, @@ -15,12 +17,14 @@ import MethodsList from 'lib/components/MethodsList/methods-list'; import SchemaManager from 'lib/utils/SchemaManager'; describe('Redoc components', () => { - describe('ApiInfo Component', () => { + describe('MethodsList Component', () => { let builder; let component; let fixture; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: new SchemaManager()}) + provide(SchemaManager, {useValue: new SchemaManager()}), + provide(OptionsManager, {useClass: OptionsManager}), + provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}) ]); beforeEach(injectAsync([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { builder = tcb; @@ -32,7 +36,7 @@ describe('Redoc components', () => { component = getChildDebugElement(fixture.debugElement, 'methods-list').componentInstance; fixture.detectChanges(); done(); - }, err => { throw err; }); + }, err => done.fail(err) ); }); diff --git a/lib/components/ParamsList/params-list.html b/lib/components/ParamsList/params-list.html index fbbdb382..e4583e9a 100644 --- a/lib/components/ParamsList/params-list.html +++ b/lib/components/ParamsList/params-list.html @@ -2,12 +2,16 @@
- {{param.name}} + {{param.name}}
- {{param.type}} + {{param._displayType}} {{param._displayFormat}} Required +
+ {{enumItem.val | json}} +
@@ -19,7 +23,7 @@
- - + +
diff --git a/lib/components/ParamsList/params-list.js b/lib/components/ParamsList/params-list.js index 2e296513..d027db7c 100644 --- a/lib/components/ParamsList/params-list.js +++ b/lib/components/ParamsList/params-list.js @@ -2,12 +2,13 @@ import {RedocComponent, BaseComponent} from '../base'; import JsonSchema from '../JsonSchema/json-schema'; +import JsonSchemaLazy from '../JsonSchema/json-schema-lazy'; @RedocComponent({ selector: 'params-list', templateUrl: './lib/components/ParamsList/params-list.html', styleUrls: ['./lib/components/ParamsList/params-list.css'], - directives: [JsonSchema] + directives: [JsonSchema, JsonSchemaLazy] }) export default class ParamsList extends BaseComponent { constructor(schemaMgr) { @@ -26,6 +27,11 @@ export default class ParamsList extends BaseComponent { this.data.bodyParam = bodyParam; } + params = params.map((paramData) => { + let propPointer = paramData._pointer; + return JsonSchema.injectPropData(paramData, paramData.name, propPointer); + }); + this.data.noParams = !(params.length || this.data.bodyParam); this.data.params = params; } diff --git a/lib/components/ParamsList/params-list.scss b/lib/components/ParamsList/params-list.scss index 23c9b10a..2475d8f7 100644 --- a/lib/components/ParamsList/params-list.scss +++ b/lib/components/ParamsList/params-list.scss @@ -28,23 +28,27 @@ display: table-row; } -.param:first-of-type .param-name:before { - content: ""; - display: block; - position: absolute; - left: -$lines-width; - top: 0; - border-left: $line-border-erase; - height: ($param-name-height/2) + $cell-padding; +.param:last-of-type > .param-name { + border-left: 0; + &:after { + content: ""; + display: block; + position: absolute; + left: 0; + border-left: $line-border; + height: ($param-name-height/2) + $cell-padding + $lines-width; + background-color: white; + top: 0; + } } -.param:last-of-type .param-name:after { +.param:first-of-type .param-name:after { content: ""; display: block; position: absolute; left: -$lines-width; border-left: $line-border-erase; - top: ($param-name-height/2) + $cell-padding + $lines-width; + height: ($param-name-height/2) + $cell-padding; background-color: white; - bottom: 0; + top: 0; } diff --git a/lib/components/Redoc/redoc-loading-styles.scss b/lib/components/Redoc/redoc-loading-styles.scss new file mode 100644 index 00000000..0e4f4bd9 --- /dev/null +++ b/lib/components/Redoc/redoc-loading-styles.scss @@ -0,0 +1,37 @@ +redoc.loading { + position: relative; + display: block; + min-height:350px; +} + +@keyframes move { + 0% {transform: translateY(10px)} + 25% {transform: translateY(0px)} + 50% {transform: translateY(10px)} + 75% {transform: translateY(20px)} + 100% {transform: translateY(10px)} +} + +redoc.loading:before { + content: "Loading..."; + font-size: 28px; + text-align: center; + padding-top: 40px; + color: #3F5C9C; + font-weight: bold; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: white; + z-index: 9999; + opacity: 1; + transition: all 0.6s ease-out; + animation: 2s move linear infinite; +} + +redoc.loading-remove:before { + opacity: 0; +} diff --git a/lib/components/Redoc/redoc.html b/lib/components/Redoc/redoc.html index c72f5d40..8e166bd8 100644 --- a/lib/components/Redoc/redoc.html +++ b/lib/components/Redoc/redoc.html @@ -1,5 +1,5 @@
- `; builder = builder.overrideView( TestApp, new ViewMetadata({template: scollableDivTmpl, directives: [MethodsList, SideMenu]})); - builder.createAsync(TestApp).then(_fixture => { fixture = _fixture; component = getChildDebugElement(fixture.debugElement, 'side-menu').componentInstance; menuNativeEl = getChildDebugElement(fixture.debugElement, 'side-menu').nativeElement; - component.scrollParent = _fixture.nativeElement.children[0]; + component.options.scrollParent = _fixture.nativeElement.children[0]; + component.$scrollParent = _fixture.nativeElement.children[0]; fixture.detectChanges(); - done(); }, err => { throw err; @@ -121,14 +134,26 @@ describe('Redoc components', () => { expect(component.data).not.toBeNull(); }); - it('should scroll to method when location hash is present', (done) => { - let hash = '#pet/paths/~1pet~1findByStatus/get'; - spyOn(component.adapter, 'getLocation').and.returnValue({hash: hash}); + it('should scroll to method when location hash is present [jp]', (done) => { + let hash = '#tag/pet/paths/~1pet~1findByStatus/get'; + spyOn(component.dom, 'getLocation').and.returnValue({hash: hash}); spyOn(component, 'hashScroll').and.callThrough(); redocEvents.bootstrapped.next(); setTimeout(() => { expect(component.hashScroll).toHaveBeenCalled(); - expect(component.scrollParent.scrollTop).toBeGreaterThan(0); + expect(component.$scrollParent.scrollTop).toBeGreaterThan(0); + done(); + }); + }); + + it('should scroll to method when location hash is present [operation]', (done) => { + let hash = '#operation/getPetById'; + spyOn(component.dom, 'getLocation').and.returnValue({hash: hash}); + spyOn(component, 'hashScroll').and.callThrough(); + redocEvents.bootstrapped.next(); + setTimeout(() => { + expect(component.hashScroll).toHaveBeenCalled(); + expect(component.$scrollParent.scrollTop).toBeGreaterThan(0); done(); }); }); @@ -138,14 +163,14 @@ describe('Redoc components', () => { component.activeMethodIdx.should.be.equal(-1); let elTop = component.getCurrentMethodEl().getBoundingClientRect().bottom; - component.scrollParent.scrollTop = elTop + 1; + component.$scrollParent.scrollTop = elTop + 1; //simulate scroll down spyOn(component, 'scrollY').and.returnValue(elTop + 2); component.scrollHandler(); component.activeCatIdx.should.be.equal(1); - component.scrollParent.scrollTop = elTop - 1; + component.$scrollParent.scrollTop = elTop - 1; //simulate scroll up component.scrollY.and.returnValue(elTop - 2); component.scrollHandler(); @@ -161,10 +186,10 @@ describe('Redoc components', () => { }); it('should scroll to appropriate element when click on menu label', () => { - component.scrollParent.scrollTop.should.be.equal(0); + component.$scrollParent.scrollTop.should.be.equal(0); let menuItemEl = menuNativeEl.querySelector('li'); mouseclick(menuItemEl); - component.scrollParent.scrollTop.should.be.above(0); + component.$scrollParent.scrollTop.should.be.above(0); }); }); }); diff --git a/lib/components/base.js b/lib/components/base.js index c27c7049..c8e7146a 100644 --- a/lib/components/base.js +++ b/lib/components/base.js @@ -5,6 +5,8 @@ import SchemaManager from '../utils/SchemaManager'; import JsonPointer from '../utils/JsonPointer'; import {MarkedPipe, JsonPointerEscapePipe} from '../utils/pipes'; +export { SchemaManager }; + // common inputs for all components let commonInputs = ['pointer']; // json pointer to the schema chunk @@ -77,6 +79,7 @@ export function RedocComponent(options) { * Generic Component * @class */ +@Reflect.metadata('parameters', [[SchemaManager]]) export class BaseComponent { constructor(schemaMgr) { this.schemaMgr = schemaMgr; @@ -208,4 +211,3 @@ export class BaseComponent { */ destroy() {} } -BaseComponent.parameters = [[SchemaManager]]; diff --git a/lib/index.js b/lib/index.js index 70104b76..1a0b8775 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,10 +1,7 @@ 'use strict'; import {Redoc} from './components/index'; -import {enableProdMode} from 'angular2/core'; - export var init = Redoc.init; window.Redoc = Redoc; -enableProdMode(); Redoc.autoInit(); diff --git a/lib/options.js b/lib/options.js index 8f2a1a8e..689310a5 100644 --- a/lib/options.js +++ b/lib/options.js @@ -1,28 +1,22 @@ 'use strict'; -export var options = { - scrollYOffset: 0 +import {isFunction, isString} from 'angular2/src/facade/lang'; +import {BrowserDomAdapter} from 'angular2/platform/browser'; +import {global} from 'angular2/src/facade/lang'; + +var defaults = { + scrollYOffset: 0, + disableLazySchemas: false, + debugMode: global.redocDebugMode }; -// singleton +var OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas']); + +@Reflect.metadata('parameters', [[BrowserDomAdapter]]) export default class OptionsManager { constructor() { - if (OptionsManager.prototype._instance) { - return OptionsManager.prototype._instance; - } - - OptionsManager.prototype._instance = this; - - this._defaults = { - scrollYOffset: 0, - disableLazySchemas: false - }; - - this._options = {}; - } - - static instance() { - return new OptionsManager(); + this._options = defaults; + this.dom = new BrowserDomAdapter(); } get options() { @@ -30,6 +24,50 @@ export default class OptionsManager { } set options(opts) { - this._options = Object.assign({}, this._defaults, opts); + this._options = Object.assign(this._options, opts); + } + + parseOptions(el) { + let parsedOpts; + let attributesMap = this.dom.attributeMap(el); + parsedOpts = {}; + Array.from(attributesMap.keys()) + //camelCasify + .map(k => ({ + attrName: k, + name: k.replace(/-(.)/g, (m, $1) => $1.toUpperCase()) + }) + ) + .filter(option => OPTION_NAMES.has(option.name)) + .forEach(option => { + parsedOpts[option.name] = attributesMap.get(option.attrName); + }); + + this.options = parsedOpts; + this._normalizeOptions(); + } + + _normalizeOptions() { + // modify scrollYOffset to always be a function + if (!isFunction(this._options.scrollYOffset)) { + if (isFinite(this._options.scrollYOffset)) { + // if number specified create function that returns this value + let numberOffset = parseFloat(this._options.scrollYOffset); + this.options.scrollYOffset = () => numberOffset; + } else { + // if selector or node function that returns bottom offset of this node + let el = this._options.scrollYOffset; + if (!(el instanceof Node)) { + el = this.dom.query(el); + } + if (!el) { + this._options.scrollYOffset = () => 0; + } else { + this._options.scrollYOffset = () => el.offsetTop + el.offsetHeight; + } + } + } + + if (isString(this._options.disableLazySchemas)) this._options.disableLazySchemas = true; } } diff --git a/lib/utils/JsonPointer.js b/lib/utils/JsonPointer.js index 165bcffd..8dd8fc90 100644 --- a/lib/utils/JsonPointer.js +++ b/lib/utils/JsonPointer.js @@ -63,4 +63,6 @@ export class JsonPointer extends JsonPointerLib { JsonPointerLib._origParse = JsonPointerLib.parse; JsonPointerLib.parse = JsonPointer.parse; + +Object.assign(JsonPointer, JsonPointerLib); export default JsonPointer; diff --git a/lib/utils/SchemaManager.js b/lib/utils/SchemaManager.js index 254fd88d..2c11af6a 100644 --- a/lib/utils/SchemaManager.js +++ b/lib/utils/SchemaManager.js @@ -150,7 +150,11 @@ export default class SchemaManager { } if (tagDetails['x-traitTag']) continue; if (!tagDetails.methods) tagDetails.methods = []; - tagDetails.methods.push({pointer: methodPointer, summary: methodSummary}); + tagDetails.methods.push({ + pointer: methodPointer, + summary: methodSummary, + operationId: methodInfo.operationId + }); } } } diff --git a/lib/utils/browser-update.js b/lib/utils/browser-update.js new file mode 100644 index 00000000..7e08bc7c --- /dev/null +++ b/lib/utils/browser-update.js @@ -0,0 +1,10 @@ +/*eslint no-unused-vars: 0*/ +/*eslint strict: 0*/ +var $buoop = { vs: {i:9, f:25, o:12.1, s:7}, c:2 }; +function $buo_f(){ + var e = document.createElement('script'); + e.src = '//browser-update.org/update.min.js'; + document.body.appendChild(e); +} +try {document.addEventListener('DOMContentLoaded', $buo_f, false);} +catch(e){window.attachEvent('onload', $buo_f);} diff --git a/lib/utils/pipes.js b/lib/utils/pipes.js index df4bd4e2..45f5af15 100644 --- a/lib/utils/pipes.js +++ b/lib/utils/pipes.js @@ -4,7 +4,7 @@ import {Pipe} from 'angular2/core'; import {isString, stringify, isBlank} from 'angular2/src/facade/lang'; import {BaseException} from 'angular2/src/facade/exceptions'; import {JsonPointer} from './JsonPointer'; -import marked from 'marked'; + import Prism from 'prismjs'; import 'prismjs/components/prism-actionscript.js'; import 'prismjs/components/prism-c.js'; @@ -29,6 +29,8 @@ import 'prismjs/components/prism-vim.js'; import 'prismjs/themes/prism-dark.css!css'; +import marked from 'marked'; + marked.setOptions({ renderer: new marked.Renderer(), gfm: true, diff --git a/package.json b/package.json index 02d313da..47ac0303 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "redoc", "description": "Swagger-generated API Reference Documentation", - "version": "0.5.2", + "version": "0.6.0", "repository": { "type": "git", "url": "git://github.com/Rebilly/ReDoc" @@ -9,7 +9,6 @@ "main": "dist/redoc.min.js", "scripts": { "test": "gulp lint && ./build/run_tests.sh", - "prepublish": "gulp build", "jspm-install": "jspm install", "start": "gulp serve", "build-dist": "gulp build", @@ -29,8 +28,9 @@ "jspm": { "configFile": "system.config.js", "dependencies": { - "angular2": "npm:angular2@^2.0.0-beta.0", + "angular2": "npm:angular2@2.0.0-beta.6", "es6-shim": "github:es-shims/es6-shim@^0.33.6", + "json": "github:systemjs/plugin-json@^0.1.0", "json-formatter-js": "npm:json-formatter-js@^0.2.0", "json-pointer": "npm:json-pointer@^0.3.0", "json-schema-instantiator": "npm:json-schema-instantiator@^0.3.0", diff --git a/system.config.js b/system.config.js index b3f9a4ff..ced0e028 100644 --- a/system.config.js +++ b/system.config.js @@ -37,7 +37,7 @@ System.config({ }, map: { - "angular2": "npm:angular2@2.0.0-beta.0", + "angular2": "npm:angular2@2.0.0-beta.6", "babel": "npm:babel-core@5.8.34", "babel-runtime": "npm:babel-runtime@5.8.34", "clean-css": "npm:clean-css@3.4.6", @@ -135,14 +135,14 @@ System.config({ "path": "github:jspm/nodelibs-path@0.1.0", "process": "github:jspm/nodelibs-process@0.1.2" }, - "npm:angular2@2.0.0-beta.0": { + "npm:angular2@2.0.0-beta.6": { "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "es6-promise": "npm:es6-promise@3.0.2", + "es6-promise": "npm:es6-promise@3.1.2", "es6-shim": "npm:es6-shim@0.33.13", "process": "github:jspm/nodelibs-process@0.1.2", "reflect-metadata": "npm:reflect-metadata@0.1.2", "rxjs": "npm:rxjs@5.0.0-beta.0", - "zone.js": "npm:zone.js@0.5.10" + "zone.js": "npm:zone.js@0.5.14" }, "npm:argparse@1.0.3": { "assert": "github:jspm/nodelibs-assert@0.1.0", @@ -153,9 +153,9 @@ System.config({ "sprintf-js": "npm:sprintf-js@1.0.3", "util": "github:jspm/nodelibs-util@0.1.0" }, - "npm:asn1.js@4.3.0": { + "npm:asn1.js@4.4.0": { "assert": "github:jspm/nodelibs-assert@0.1.0", - "bn.js": "npm:bn.js@4.6.4", + "bn.js": "npm:bn.js@4.10.3", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "inherits": "npm:inherits@2.0.1", "minimalistic-assert": "npm:minimalistic-assert@1.0.0", @@ -199,11 +199,14 @@ System.config({ "readable-stream": "npm:readable-stream@2.0.5", "util": "github:jspm/nodelibs-util@0.1.0" }, + "npm:bn.js@4.10.3": { + "buffer": "github:jspm/nodelibs-buffer@0.1.0" + }, "npm:boom@2.10.1": { "hoek": "npm:hoek@2.16.3", "http": "github:jspm/nodelibs-http@1.7.1" }, - "npm:browserify-aes@1.0.5": { + "npm:browserify-aes@1.0.6": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", "buffer-xor": "npm:buffer-xor@1.0.3", "cipher-base": "npm:cipher-base@1.0.2", @@ -215,7 +218,7 @@ System.config({ "systemjs-json": "github:systemjs/plugin-json@0.1.0" }, "npm:browserify-cipher@1.0.0": { - "browserify-aes": "npm:browserify-aes@1.0.5", + "browserify-aes": "npm:browserify-aes@1.0.6", "browserify-des": "npm:browserify-des@1.0.0", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", @@ -229,20 +232,20 @@ System.config({ "inherits": "npm:inherits@2.0.1" }, "npm:browserify-rsa@4.0.0": { - "bn.js": "npm:bn.js@4.6.4", + "bn.js": "npm:bn.js@4.10.3", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "constants": "github:jspm/nodelibs-constants@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", "randombytes": "npm:randombytes@2.0.2" }, "npm:browserify-sign@4.0.0": { - "bn.js": "npm:bn.js@4.6.4", + "bn.js": "npm:bn.js@4.10.3", "browserify-rsa": "npm:browserify-rsa@4.0.0", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "create-hash": "npm:create-hash@1.1.2", "create-hmac": "npm:create-hmac@1.1.4", "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "elliptic": "npm:elliptic@6.0.2", + "elliptic": "npm:elliptic@6.2.3", "inherits": "npm:inherits@2.0.1", "parse-asn1": "npm:parse-asn1@5.0.0", "stream": "github:jspm/nodelibs-stream@0.1.0" @@ -332,10 +335,10 @@ System.config({ "buffer": "github:jspm/nodelibs-buffer@0.1.0" }, "npm:create-ecdh@4.0.0": { - "bn.js": "npm:bn.js@4.6.4", + "bn.js": "npm:bn.js@4.10.3", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "elliptic": "npm:elliptic@6.0.2" + "elliptic": "npm:elliptic@6.2.3" }, "npm:create-hash@1.1.2": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", @@ -363,14 +366,14 @@ System.config({ "create-ecdh": "npm:create-ecdh@4.0.0", "create-hash": "npm:create-hash@1.1.2", "create-hmac": "npm:create-hmac@1.1.4", - "diffie-hellman": "npm:diffie-hellman@5.0.1", + "diffie-hellman": "npm:diffie-hellman@5.0.2", "inherits": "npm:inherits@2.0.1", "pbkdf2": "npm:pbkdf2@3.0.4", "public-encrypt": "npm:public-encrypt@4.0.0", "randombytes": "npm:randombytes@2.0.2" }, - "npm:dashdash@1.12.1": { - "assert-plus": "npm:assert-plus@0.1.5", + "npm:dashdash@1.12.2": { + "assert-plus": "npm:assert-plus@0.2.0", "fs": "github:jspm/nodelibs-fs@0.1.2", "path": "github:jspm/nodelibs-path@0.1.0", "process": "github:jspm/nodelibs-process@0.1.2", @@ -393,8 +396,8 @@ System.config({ "inherits": "npm:inherits@2.0.1", "minimalistic-assert": "npm:minimalistic-assert@1.0.0" }, - "npm:diffie-hellman@5.0.1": { - "bn.js": "npm:bn.js@4.6.4", + "npm:diffie-hellman@5.0.2": { + "bn.js": "npm:bn.js@4.10.3", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", "miller-rabin": "npm:miller-rabin@4.0.0", @@ -406,14 +409,14 @@ System.config({ "crypto": "github:jspm/nodelibs-crypto@0.1.0", "jsbn": "npm:jsbn@0.1.0" }, - "npm:elliptic@6.0.2": { - "bn.js": "npm:bn.js@4.6.4", + "npm:elliptic@6.2.3": { + "bn.js": "npm:bn.js@4.10.3", "brorand": "npm:brorand@1.0.5", "hash.js": "npm:hash.js@1.0.3", "inherits": "npm:inherits@2.0.1", "systemjs-json": "github:systemjs/plugin-json@0.1.0" }, - "npm:es6-promise@3.0.2": { + "npm:es6-promise@3.1.2": { "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:es6-shim@0.33.13": { @@ -543,7 +546,7 @@ System.config({ "buffer": "github:jspm/nodelibs-buffer@0.1.0", "call-me-maybe": "npm:call-me-maybe@1.0.1", "debug": "npm:debug@2.2.0", - "es6-promise": "npm:es6-promise@3.0.2", + "es6-promise": "npm:es6-promise@3.1.2", "events": "github:jspm/nodelibs-events@0.1.1", "fs": "github:jspm/nodelibs-fs@0.1.2", "http": "github:jspm/nodelibs-http@1.7.1", @@ -584,7 +587,7 @@ System.config({ "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:miller-rabin@4.0.0": { - "bn.js": "npm:bn.js@4.6.4", + "bn.js": "npm:bn.js@4.10.3", "brorand": "npm:brorand@1.0.5" }, "npm:mime-db@1.21.0": { @@ -616,8 +619,8 @@ System.config({ "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:parse-asn1@5.0.0": { - "asn1.js": "npm:asn1.js@4.3.0", - "browserify-aes": "npm:browserify-aes@1.0.5", + "asn1.js": "npm:asn1.js@4.4.0", + "browserify-aes": "npm:browserify-aes@1.0.6", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "create-hash": "npm:create-hash@1.1.2", "evp_bytestokey": "npm:evp_bytestokey@1.0.0", @@ -637,10 +640,7 @@ System.config({ "systemjs-json": "github:systemjs/plugin-json@0.1.0" }, "npm:pinkie-promise@2.0.0": { - "pinkie": "npm:pinkie@2.0.1" - }, - "npm:pinkie@2.0.1": { - "process": "github:jspm/nodelibs-process@0.1.2" + "pinkie": "npm:pinkie@2.0.4" }, "npm:prismjs@1.3.0": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", @@ -654,7 +654,7 @@ System.config({ "assert": "github:jspm/nodelibs-assert@0.1.0" }, "npm:public-encrypt@4.0.0": { - "bn.js": "npm:bn.js@4.6.4", + "bn.js": "npm:bn.js@4.10.3", "browserify-rsa": "npm:browserify-rsa@4.0.0", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "create-hash": "npm:create-hash@1.1.2", @@ -758,7 +758,7 @@ System.config({ "assert-plus": "npm:assert-plus@0.2.0", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "dashdash": "npm:dashdash@1.12.1", + "dashdash": "npm:dashdash@1.12.2", "ecc-jsbn": "npm:ecc-jsbn@0.1.1", "jodid25519": "npm:jodid25519@1.0.2", "jsbn": "npm:jsbn@0.1.0", @@ -793,7 +793,7 @@ System.config({ "buffer": "github:jspm/nodelibs-buffer@0.1.0", "call-me-maybe": "npm:call-me-maybe@1.0.1", "debug": "npm:debug@2.2.0", - "es6-promise": "npm:es6-promise@3.0.2", + "es6-promise": "npm:es6-promise@3.1.2", "events": "github:jspm/nodelibs-events@0.1.1", "fs": "github:jspm/nodelibs-fs@0.1.2", "http": "github:jspm/nodelibs-http@1.7.1", @@ -867,8 +867,8 @@ System.config({ "util": "github:jspm/nodelibs-util@0.1.0", "validator": "npm:validator@4.5.0" }, - "npm:zone.js@0.5.10": { - "es6-promise": "npm:es6-promise@3.0.2", + "npm:zone.js@0.5.14": { + "es6-promise": "npm:es6-promise@3.1.2", "process": "github:jspm/nodelibs-process@0.1.2" } } diff --git a/tests/helpers.js b/tests/helpers.js index 3ce7c4ca..90f2bc14 100644 --- a/tests/helpers.js +++ b/tests/helpers.js @@ -1,27 +1,20 @@ 'use strict'; -import {BrowserDomAdapter} from 'angular2/platform/browser'; -BrowserDomAdapter.makeCurrent(); +import {By} from 'angular2/platform/browser'; /** Gets a child DebugElement by tag name. */ export function getChildDebugElement(parent, tagName) { - return parent.query(debugEl => { - return debugEl.nativeElement.tagName && debugEl.nativeElement.tagName.toLowerCase() === tagName; - }); + return parent.query(By.css(tagName)); } /** Gets a child DebugElement by Component Type. */ export function getChildDebugElementByType(parent, type) { - return parent.query(debugEl => { - return debugEl.componentInstance instanceof type; - }); + return parent.query(By.directive(type)); } /** Gets a child DebugElements by tag name. */ export function getChildDebugElementAll(parent, tagName) { - return parent.queryAll(debugEl => { - return debugEl.nativeElement.tagName && debugEl.nativeElement.tagName.toLowerCase() === tagName; - }); + return parent.queryAll(By.css(tagName)); } export function mouseclick( element ) { diff --git a/tests/setup.js b/tests/setup.js new file mode 100644 index 00000000..d008172c --- /dev/null +++ b/tests/setup.js @@ -0,0 +1,13 @@ +'use strict'; + +import {setBaseTestProviders} from 'angular2/testing'; + +import { + TEST_BROWSER_PLATFORM_PROVIDERS, + TEST_BROWSER_APPLICATION_PROVIDERS +} from 'angular2/platform/testing/browser'; +import { + + ELEMENT_PROBE_PROVIDERS_PROD_MODE +} from 'angular2/platform/browser'; +setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, [TEST_BROWSER_APPLICATION_PROVIDERS, ELEMENT_PROBE_PROVIDERS_PROD_MODE]); diff --git a/tests/unit/SchemaManager.spec.js b/tests/unit/SchemaManager.spec.js index 0a2bfbf8..1ec4ec87 100644 --- a/tests/unit/SchemaManager.spec.js +++ b/tests/unit/SchemaManager.spec.js @@ -165,7 +165,7 @@ describe('Utils', () => { info.should.be.an.Object(); info.methods.should.be.an.Array(); for (let methodInfo of info.methods) { - methodInfo.should.have.keys('pointer', 'summary'); + methodInfo.should.have.properties(['pointer', 'summary']); let methSchema = schemaMgr.byPointer(methodInfo.pointer); expect(methSchema).not.toBeNull(); if (methSchema.summary) {