Add tslint

This commit is contained in:
Roman Hotsiy 2016-06-13 20:54:24 +03:00
parent 4498884f62
commit 4f39ab9edc
34 changed files with 272 additions and 205 deletions

View File

@ -9,7 +9,7 @@ var paths = {
output: 'dist/',
tmp: '.tmp/',
demo: 'demo/**/*',
tests: '{lib,tests}/**/*.spec.js',
tests: '{lib,tests}/**/*.spec.ts',
releases: 'demo/releases/'
}

View File

@ -1,10 +1,15 @@
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var tslint = require('gulp-tslint');
var paths = require('../paths');
gulp.task('lint', function () {
return gulp.src([paths.source, paths.tests])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
.pipe(tslint({
rulesDirectory: 'node_modules/codelyzer'
}))
.pipe(tslint.report(require('tslint-stylish'), {
emitError: true,
sort: true,
bell: true
}));
});

View File

@ -34,7 +34,7 @@ describe('Redoc components', () => {
})));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
component = getChildDebugElement(fixture.debugElement, 'api-info').componentInstance;
fixture.detectChanges();
@ -67,5 +67,5 @@ describe('Redoc components', () => {
template:
`<api-info></api-info>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -14,7 +14,7 @@ export class ApiInfo extends BaseComponent {
constructor(schemaMgr:SchemaManager, private optionsService:OptionsService) {
super(schemaMgr);
}
prepareModel() {
this.data = this.componentSchema.info;
this.specUrl = this.optionsService.options.specUrl;

View File

@ -34,7 +34,7 @@ describe('Redoc components', () => {
return schemaMgr.load(schemaUrl);
})));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
component = getChildDebugElement(fixture.debugElement, 'api-logo').componentInstance;
fixture.detectChanges();
@ -49,7 +49,7 @@ describe('Redoc components', () => {
});
it('should not display image when no x-logo', () => {
component.data.should.be.empty;
component.data.should.be.empty();
let nativeElement = getChildDebugElement(fixture.debugElement, 'api-logo').nativeElement;
let imgElement = nativeElement.querySelector('img');
expect(imgElement).toBeNull();
@ -74,5 +74,5 @@ describe('Redoc components', () => {
template:
`<api-logo></api-logo>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -9,7 +9,7 @@ import {RedocComponent, BaseComponent, SchemaManager} from '../base';
})
export class ApiLogo extends BaseComponent {
data:any = {};
constructor(schemaMgr:SchemaManager) {
super(schemaMgr);
}

View File

@ -28,7 +28,7 @@ describe('Redoc components', () => {
instance: {
pointer: ''
},
hostView: {changeDetectorRef: {detectChanges : function() {} }}
hostView: { changeDetectorRef: {detectChanges : () => undefined} }
};
beforeEachProviders(() => [
provide(SchemaManager, {useValue: schemaMgr})
@ -39,7 +39,7 @@ describe('Redoc components', () => {
spyOn(loader, 'loadNextToLocation').and.returnValue({then: (fn) => fn(appRefMock)});
}));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
let debugEl = getChildDebugElement(fixture.debugElement, 'json-schema-lazy');
component = <JsonSchemaLazy>debugEl.componentInstance;
@ -87,5 +87,5 @@ describe('Redoc components', () => {
template:
`<json-schema-lazy></json-schema-lazy>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -28,7 +28,7 @@ describe('Redoc components', () => {
builder = tcb;
}));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
let debugEl = getChildDebugElement(fixture.debugElement, 'json-schema');
component = debugEl.componentInstance;
@ -70,5 +70,5 @@ describe('Redoc components', () => {
template:
`<json-schema></json-schema>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -22,7 +22,16 @@ export class JsonSchema extends BaseComponent {
@Input() nestOdd: boolean;
@Input() childFor: string;
@Input() isRequestSchema: boolean;
static injectPropertyData(propertySchema, propertyName, propPointer, hostPointer?) {
propertySchema = Object.assign({}, propertySchema);
propertySchema._name = propertyName;
runInjectors(propertySchema, propertySchema, propPointer, hostPointer);
return propertySchema;
}
constructor(schemaMgr:SchemaManager, elementRef:ElementRef) {
super(schemaMgr);
this.$element = elementRef.nativeElement;
@ -137,24 +146,6 @@ export class JsonSchema extends BaseComponent {
return JsonSchema.injectPropertyData(addProps, '<Additional Properties> *',
JsonPointer.join(addProps._pointer || schema._pointer || this.pointer, ['additionalProperties']));
}
static injectPropertyData(propertySchema, propertyName, propPointer, hostPointer?) {
propertySchema = Object.assign({}, propertySchema);
propertySchema._name = propertyName;
runInjectors(propertySchema, propertySchema, propPointer, hostPointer);
return propertySchema;
}
}
function runInjectors(injectTo, propertySchema, propertyPointer, hostPointer?) {
for (var injName in injectors) {
let injector = injectors[injName];
if (injector.check(propertySchema)) {
injector.inject(injectTo, propertySchema, propertyPointer, hostPointer);
}
}
}
const injectors = {
@ -283,3 +274,12 @@ const injectors = {
}
}
};
function runInjectors(injectTo, propertySchema, propertyPointer, hostPointer?) {
for (var injName in injectors) {
let injector = injectors[injName];
if (injector.check(propertySchema)) {
injector.inject(injectTo, propertySchema, propertyPointer, hostPointer);
}
}
}

View File

@ -27,7 +27,7 @@ describe('Redoc components', () => {
return schemaMgr.load('/tests/schemas/extended-petstore.yml');
})));
beforeEach((done) => {
builder.createAsync(TestApp).then(fixture => {
builder.createAsync(TestAppComponent).then(fixture => {
component = getChildDebugElement(fixture.debugElement, 'method').componentInstance;
fixture.detectChanges();
done();
@ -47,7 +47,7 @@ describe('Redoc components', () => {
it('should main tag', () => {
component.data.methodInfo.tags.should.be.empty;
component.data.methodInfo.tags.should.be.empty();
});
});
});
@ -61,5 +61,5 @@ describe('Redoc components', () => {
template:
`<method pointer='#/paths/~1user~1{username}/put'></method>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -29,7 +29,7 @@ describe('Redoc components', () => {
return schemaMgr.load('/tests/schemas/methods-list-component.json');
})));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
component = getChildDebugElement(fixture.debugElement, 'methods-list').componentInstance;
fixture.detectChanges();
@ -46,7 +46,7 @@ describe('Redoc components', () => {
expect(component.data.tags).not.toBeNull();
component.data.tags.should.have.lengthOf(2);
component.data.tags[0].name.should.be.equal('traitTag');
component.data.tags[0].methods.should.be.empty;
component.data.tags[0].methods.should.be.empty();
component.data.tags[1].name.should.be.equal('tag1');
component.data.tags[1].methods.should.have.lengthOf(2);
});
@ -59,5 +59,5 @@ describe('Redoc components', () => {
template:
`<methods-list></methods-list>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -16,9 +16,9 @@ function safePush(obj, prop, item) {
directives: [JsonSchema, JsonSchemaLazy]
})
export class ParamsList extends BaseComponent {
data:any;
constructor(schemaMgr:SchemaManager) {
super(schemaMgr);
}

View File

@ -42,7 +42,7 @@ describe('Redoc components', () => {
it('should init component', (done) => {
builder.createAsync(TestApp).then(fixture => {
builder.createAsync(TestAppComponent).then(fixture => {
let component = getChildDebugElement(fixture.debugElement, 'redoc').componentInstance;
expect(component).not.toBeNull();
fixture.destroy();
@ -51,12 +51,12 @@ describe('Redoc components', () => {
});
it('should init components tree without errors', (done) => {
builder.createAsync(TestApp).then(fixture => {
builder.createAsync(TestAppComponent).then(fixture => {
(() => fixture.detectChanges()).should.not.throw();
fixture.destroy();
done();
}, err => {
return done.fail(err)
return done.fail(err);
});
});
});
@ -116,7 +116,7 @@ describe('Redoc components', () => {
})));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
element = getChildDebugElement(fixture.debugElement, 'methods-list').nativeElement;
destroySpy = jasmine.createSpy('spy');
@ -190,5 +190,5 @@ describe('Redoc components', () => {
template:
`<redoc disable-lazy-schemas></redoc>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -34,26 +34,11 @@ var _modeLocked = false;
onPushOnly: false
})
export class Redoc extends BaseComponent {
private element: any;
options: any;
static appRef: ComponentRef<any>;
constructor(schemaMgr: SchemaManager, optionsMgr:OptionsService, elementRef:ElementRef,
public events:RedocEventsService) {
super(schemaMgr);
this.element = elementRef.nativeElement;
//parse options (top level component doesn't support inputs)
optionsMgr.parseOptions( this.element );
optionsMgr.options.$scrollParent = detectScollParent( this.element );
this.options = optionsMgr.options;
this.events = events;
}
options: any;
ngAfterViewInit() {
setTimeout( () => {
this.events.bootstrapped.next({});
});
}
private element: any;
static showLoadingAnimation() {
let elem = dom.query('redoc');
@ -143,7 +128,24 @@ export class Redoc extends BaseComponent {
// Redoc destroy removes host element, so need to restore it
elClone.innerHTML = 'Loading...';
parent && parent.insertBefore(elClone, nextSibling);
if (parent) parent.insertBefore(elClone, nextSibling);
}
}
constructor(schemaMgr: SchemaManager, optionsMgr:OptionsService, elementRef:ElementRef,
public events:RedocEventsService) {
super(schemaMgr);
this.element = elementRef.nativeElement;
//parse options (top level component doesn't support inputs)
optionsMgr.parseOptions( this.element );
optionsMgr.options.$scrollParent = detectScollParent( this.element );
this.options = optionsMgr.options;
this.events = events;
}
ngAfterViewInit() {
setTimeout( () => {
this.events.bootstrapped.next({});
});
}
}

View File

@ -1,5 +1,5 @@
<div class="snippet">
<!-- in case sample is not available for some reason -->
<pre *ngIf="data.sample == null"> Sample unavailable </pre>
<pre *ngIf="data.sample == undefined"> Sample unavailable </pre>
<pre innerHtml="{{data.sample | jsonFormatter}}"></pre>
</div>

View File

@ -40,7 +40,7 @@ describe('Redoc components', () => {
})));
beforeEach((done) => {
builder.createAsync(TestApp).then(_fixture => {
builder.createAsync(TestAppComponent).then(_fixture => {
fixture = _fixture;
component = getChildDebugElement(fixture.debugElement, 'side-menu').componentInstance;
fixture.detectChanges();
@ -69,5 +69,5 @@ describe('Redoc components', () => {
`<side-menu></side-menu>
<methods-list></methods-list>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -24,8 +24,8 @@ export class SideMenu extends BaseComponent {
activeItemCaption: string;
options: any;
data: any;
constructor(schemaMgr:SchemaManager, elementRef:ElementRef, private dom:BrowserDomAdapter,
private scrollService:ScrollService, private menuService:MenuService, private hash:Hash,
constructor(schemaMgr:SchemaManager, elementRef:ElementRef, private dom:BrowserDomAdapter,
private scrollService:ScrollService, private menuService:MenuService, private hash:Hash,
optionsService:OptionsService, private detectorRef:ChangeDetectorRef) {
super(schemaMgr);
this.$element = elementRef.nativeElement;

View File

@ -284,6 +284,7 @@ describe('Redoc components', () => {
});
xdescribe('Merge array allOf', () => {
//emtpy
});
});
});

View File

@ -13,7 +13,7 @@ let commonInputs = ['pointer']; // json pointer to the schema chunk
// internal helper function
function safeConcat(a, b) {
let res = a && a.slice() || [];
b = (b == null) ? [] : b;
b = (b == undefined) ? [] : b;
return res.concat(b);
}
@ -33,7 +33,7 @@ function defaults(target, src) {
}
function snapshot(obj) {
if(obj == null || typeof(obj) != 'object') {
if(obj == undefined || typeof(obj) !== 'object') {
return obj;
}
@ -97,6 +97,70 @@ export function RedocComponent(options) {
export class BaseComponent {
componentSchema: any = null;
pointer: String;
static joinAllOf(schema: any, opts?: any) {
function merge(into, schemas) {
for (let subSchema of schemas) {
if (opts && opts.omitParent && subSchema.discriminator) continue;
// TODO: add support for merge array schemas
if (typeof subSchema !== 'object') {
let errMessage = `Items of allOf should be Object: ${typeof subSchema} found
${subSchema}`;
throw new Error(errMessage);
}
if (into.type && subSchema.type && into.type !== subSchema.type) {
let errMessage = `allOf merging error: schemas with different types can't be merged`;
throw new Error(errMessage);
}
if (into.type === 'array') {
console.warn('allOf: subschemas with type array are not supported yet');
}
// TODO: add check if can be merged correctly (no different properties with the same name)
into.type = into.type || subSchema.type;
if (into.type === 'object' && subSchema.properties) {
if (!into.properties) into.properties = {};
Object.assign(into.properties, subSchema.properties);
Object.keys(subSchema.properties).forEach(propName => {
if (!subSchema.properties[propName]._pointer) {
subSchema.properties[propName]._pointer = subSchema._pointer ?
JsonPointer.join(subSchema._pointer, ['properties', propName]) : null;
}
});
}
if (into.type === 'object' && subSchema.required) {
if (!into.required) into.required = [];
into.required.push(...subSchema.required);
}
// don't merge _pointer
subSchema._pointer = null;
defaults(into, subSchema);
}
into.allOf = null;
}
function traverse(obj) {
if (obj === undefined || typeof(obj) !== 'object') {
return;
}
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
traverse(obj[key]);
}
}
if (obj.allOf) {
merge(obj, obj.allOf);
}
}
traverse(schema);
}
constructor(public schemaMgr: SchemaManager) {
}
@ -168,84 +232,27 @@ export class BaseComponent {
this.componentSchema = snapshot(resolve(schema));
}
static joinAllOf(schema: any, opts?: any) {
function merge(into, schemas) {
for (let subSchema of schemas) {
if (opts && opts.omitParent && subSchema.discriminator) continue;
// TODO: add support for merge array schemas
if (typeof subSchema !== 'object') {
let errMessage = `Items of allOf should be Object: ${typeof subSchema} found
${subSchema}`;
throw new Error(errMessage);
}
if (into.type && subSchema.type && into.type !== subSchema.type) {
let errMessage = `allOf merging error: schemas with different types can't be merged`;
throw new Error(errMessage);
}
if (into.type === 'array') {
console.warn('allOf: subschemas with type array are not supported yet');
}
// TODO: add check if can be merged correctly (no different properties with the same name)
into.type = into.type || subSchema.type;
if (into.type === 'object' && subSchema.properties) {
into.properties || (into.properties = {});
Object.assign(into.properties, subSchema.properties);
Object.keys(subSchema.properties).forEach(propName => {
if (!subSchema.properties[propName]._pointer) {
subSchema.properties[propName]._pointer = subSchema._pointer ?
JsonPointer.join(subSchema._pointer, ['properties', propName]) : null;
}
});
}
if (into.type === 'object' && subSchema.required) {
into.required || (into.required = []);
into.required.push(...subSchema.required);
}
// don't merge _pointer
subSchema._pointer = null;
defaults(into, subSchema);
}
into.allOf = null;
}
function traverse(obj) {
if (obj === null || typeof(obj) !== 'object') {
return;
}
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
traverse(obj[key]);
}
}
if (obj.allOf) {
merge(obj, obj.allOf);
}
}
traverse(schema);
}
/**
* Used to prepare model based on component schema
* @abstract
*/
prepareModel() {}
prepareModel():any {
// emtpy
}
/**
* Used to initialize component. Run after prepareModel
* @abstract
*/
init() {}
init() {
// empty
}
/**
+ Used to destroy component
* @abstract
*/
destroy() {}
destroy() {
// emtpy
}
}

View File

@ -50,7 +50,7 @@ describe('Menu service', () => {
});
beforeEach((done) => {
builder.createAsync(TestApp).then((fixture) => {
builder.createAsync(TestAppComponent).then((fixture) => {
fixture.detectChanges();
done();
}).catch((err) => done.fail(err));
@ -122,5 +122,5 @@ describe('Menu service', () => {
<methods-list></methods-list>
</div>`
})
class TestApp {
class TestAppComponent {
}

View File

@ -14,7 +14,7 @@ const CHANGE = {
export class MenuService {
changed: EventEmitter<any> = new EventEmitter();
categories: any;
activeCatIdx: number = 0;
activeMethodIdx: number = -1;
activeMethodPtr: string;

View File

@ -2,7 +2,6 @@
import { Injectable } from '@angular/core';
import { isFunction, isString } from '@angular/core/src/facade/lang';
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
import { global } from '@angular/core/src/facade/lang';
const defaults = {
scrollYOffset: 0,
@ -15,7 +14,7 @@ const OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas', 'specUrl'])
@Injectable()
export class OptionsService {
private _options: any;
constructor(private dom:BrowserDomAdapter) {
this._options = defaults;
this.dom = dom;

View File

@ -26,7 +26,7 @@ export class ScrollService {
}
scrollY() {
return (this.$scrollParent.pageYOffset != null) ? this.$scrollParent.pageYOffset : this.$scrollParent.scrollTop;
return (this.$scrollParent.pageYOffset != undefined) ? this.$scrollParent.pageYOffset : this.$scrollParent.scrollTop;
}
/* returns 1 if element if above the view, 0 if in view and -1 below the view */

View File

@ -13,7 +13,7 @@ export class StickySidebar {
$redocEl: any;
@Input() scrollParent:any;
@Input() scrollYOffset:any;
constructor(elementRef:ElementRef, private dom:BrowserDomAdapter) {
this.$element = elementRef.nativeElement;
@ -30,7 +30,7 @@ export class StickySidebar {
}
unbind() {
this.cancelScrollBinding && this.cancelScrollBinding();
if (this.cancelScrollBinding) this.cancelScrollBinding();
}
updatePosition() {
@ -52,7 +52,7 @@ export class StickySidebar {
}
get scrollY() {
return (this.scrollParent.pageYOffset != null) ? this.scrollParent.pageYOffset : this.scrollParent.scrollTop;
return (this.scrollParent.pageYOffset != undefined) ? this.scrollParent.pageYOffset : this.scrollParent.scrollTop;
}
ngOnInit() {

View File

@ -29,7 +29,7 @@ export class Tabs {
tab.active = false;
});
tab.active = true;
notify && this.change.next(tab.tabTitle);
if (notify) this.change.next(tab.tabTitle);
}
selectyByTitle(tabTitle, notify = false) {
@ -47,7 +47,7 @@ export class Tabs {
} else {
prevActive.active = true;
}
notify && this.change.next(tabTitle);
if (notify) this.change.next(tabTitle);
this.changeDetector.markForCheck();
}

View File

@ -39,15 +39,15 @@ describe('Common components', () => {
});
it('should init component defaults', () => {
component.empty.should.be.false;
component.visible.should.be.false;
component.empty.should.be.false();
component.visible.should.be.false();
component.type.should.be.equal('general');
});
it('should init properties from dom params', () => {
fixture.detectChanges();
component.visible.should.be.true;
component.empty.should.be.true;
component.visible.should.be.true();
component.empty.should.be.true();
component.title.should.be.equal('Zippy');
component.type.should.be.equal('test');
});
@ -58,7 +58,7 @@ describe('Common components', () => {
expect(contentEl.innerText).toMatch('test');
});
it('should open and close zippy', () => {
it('should open and close zippy', (done) => {
fixture.detectChanges();
component.empty = false;
component.visible = true;
@ -69,13 +69,17 @@ describe('Common components', () => {
let titleEl = nativeElement.querySelector('.zippy-title');
mouseclick(titleEl);
fixture.detectChanges();
component.visible.should.be.false;
testComponent.opened.should.be.false;
component.visible.should.be.false();
testComponent.opened.should.be.false();
mouseclick(titleEl);
fixture.detectChanges();
component.visible.should.be.true;
testComponent.opened.should.be.true;
setTimeout(() => {
component.visible.should.be.true();
testComponent.opened.should.be.true();
testComponent.clickCount.should.be.equal(2);
done();
});
});
it('should disable empty zippy', () => {
@ -99,7 +103,7 @@ describe('Common components', () => {
selector: 'test-app',
directives: [Zippy],
template:
`<zippy title="Zippy" type="test" visible="true" empty="true" (open)="open()" (close)="close()">test</zippy>`
`<zippy title="Zippy" type="test" [visible]="true" [empty]="true" (open)="open()" (close)="close()">test</zippy>`
})
class TestApp {
opened: boolean;

View File

@ -1,12 +1,12 @@
'use strict';
import {Pipe} from '@angular/core';
import {isBlank} from '@angular/core/src/facade/lang';
import { Pipe, PipeTransform } from '@angular/core';
import { isBlank } from '@angular/core/src/facade/lang';
var level = 1;
const COLLAPSE_LEVEL = 2;
@Pipe({ name: 'jsonFormatter' })
export class JsonFormatter {
export class JsonFormatter implements PipeTransform {
transform(value) {
if (isBlank(value)) return value;
return jsonToHTML(value);
@ -14,7 +14,8 @@ export class JsonFormatter {
}
function htmlEncode(t) {
return t != null ? t.toString().replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : '';
return t != undefined ?
t.toString().replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : '';
}
function decorateWithSpan(value, className) {
@ -23,25 +24,22 @@ function decorateWithSpan(value, className) {
function valueToHTML(value) {
var valueType = typeof value, output = '';
if (value == null) {
if (value == undefined) {
output += decorateWithSpan('null', 'type-null');
}
else if (value && value.constructor === Array) {
} else if (value && value.constructor === Array) {
level++;
output += arrayToHTML(value);
level--;
}
else if (valueType === 'object') {
} else if (valueType === 'object') {
level++;
output += objectToHTML(value);
level--;
}
else if (valueType === 'number') {
} else if (valueType === 'number') {
output += decorateWithSpan(value, 'type-number');
}
else if (valueType === 'string') {
} else if (valueType === 'string') {
if (/^(http|https):\/\/[^\\s]+$/.test(value)) {
output += decorateWithSpan('"', 'type-string') + '<a href="' + value + '">' + htmlEncode(value) + '</a>' + decorateWithSpan('"', 'type-string');
output += decorateWithSpan('"', 'type-string') + '<a href="' + value + '">' + htmlEncode(value) + '</a>' +
decorateWithSpan('"', 'type-string');
} else {
output += decorateWithSpan('"' + value + '"', 'type-string');
}

View File

@ -6,9 +6,13 @@ import {methods as swaggerMethods} from './swagger-defs';
export class SchemaManager {
public _schema:any = {};
public apiUrl: string;
private _instance:any;
apiUrl: string;
static instance() {
return new SchemaManager();
}
constructor() {
if (SchemaManager.prototype._instance) {
return SchemaManager.prototype._instance;
@ -17,10 +21,6 @@ export class SchemaManager {
SchemaManager.prototype._instance = this;
}
static instance() {
return new SchemaManager();
}
load(url) {
let promise = new Promise((resolve, reject) => {
this._schema = {};

View File

@ -1,8 +1,8 @@
'use strict';
import {Pipe} from '@angular/core';
import {isString, stringify, isBlank} from '@angular/core/src/facade/lang';
import {BaseException} from '@angular/core/src/facade/exceptions';
import { Pipe, PipeTransform } from '@angular/core';
import { isString, stringify, isBlank } from '@angular/core/src/facade/lang';
import { BaseException } from '@angular/core/src/facade/exceptions';
import JsonPointer from './JsonPointer';
declare var Prism: any;
@ -31,7 +31,7 @@ class InvalidPipeArgumentException extends BaseException {
}
@Pipe({ name: 'keys' })
export class KeysPipe {
export class KeysPipe implements PipeTransform {
transform(value) {
if (isBlank(value)) return value;
if (typeof value !== 'object') {
@ -42,7 +42,7 @@ export class KeysPipe {
}
@Pipe({ name: 'values' })
export class ValuesPipe {
export class ValuesPipe implements PipeTransform {
transform(value) {
if (isBlank(value)) return value;
if (typeof value !== 'object') {
@ -53,7 +53,7 @@ export class ValuesPipe {
}
@Pipe({ name: 'jsonPointerEscape' })
export class JsonPointerEscapePipe {
export class JsonPointerEscapePipe implements PipeTransform {
transform(value) {
if (isBlank(value)) return value;
if (!isString(value)) {
@ -64,7 +64,7 @@ export class JsonPointerEscapePipe {
}
@Pipe({ name: 'marked' })
export class MarkedPipe {
export class MarkedPipe implements PipeTransform {
transform(value) {
if (isBlank(value)) return value;
if (!isString(value)) {
@ -83,7 +83,7 @@ const langMap = {
};
@Pipe({ name: 'prism' })
export class PrismPipe {
export class PrismPipe implements PipeTransform {
transform(value, args) {
if (isBlank(args) || args.length === 0) {
throw new BaseException('Prism pipe requires one argument');
@ -103,7 +103,7 @@ export class PrismPipe {
}
@Pipe({ name: 'encodeURIComponent' })
export class EncodeURIComponentPipe {
export class EncodeURIComponentPipe implements PipeTransform {
transform(value) {
if (isBlank(value)) return value;
if (!isString(value)) {

View File

@ -98,6 +98,7 @@
"babel-polyfill": "^6.3.14",
"branch-release": "^0.3.2",
"browser-sync": "^2.10.1",
"codelyzer": "0.0.23",
"del": "^2.2.0",
"deploy-to-gh-pages": "^1.0.0",
"dropkickjs": "github:robdel12/DropKick",
@ -142,7 +143,9 @@
"should": "^8.0.2",
"sinon": "^1.17.2",
"systemjs-builder": "^0.15.16",
"typescript": "^1.8.10",
"tslint": "^3.11.0",
"tslint-stylish": "^2.1.0-beta",
"typescript": "^1.9.0-dev.20160612-1.0",
"vinyl-paths": "^2.0.0",
"yargs": "^4.7.1",
"zone.js": "^0.6.12"

View File

@ -1,6 +1,7 @@
'use strict';
import {By} from '@angular/platform-browser';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
/** Gets a child DebugElement by tag name. */
export function getChildDebugElement(parent, tagName) {
@ -19,10 +20,7 @@ export function getChildDebugElementAll(parent, tagName) {
export function mouseclick( element ) {
// create a mouse click event
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false,
false, false, false, 0, element);
var dispatchedEvent = getDOM().createMouseEvent('click');
// send click to element
element.dispatchEvent( event );
getDOM().dispatchEvent(element, dispatchedEvent);
}

View File

@ -9,10 +9,6 @@ describe('Utils', () => {
schemaMgr = new SchemaManager();
});
it('Should initialize with empty schema', ()=> {
schemaMgr.schema.should.be.empty;
});
it('Should be a singleton', ()=> {
(new SchemaManager()).should.be.equal(schemaMgr);
SchemaManager.instance().should.be.equal(schemaMgr);
@ -50,7 +46,7 @@ describe('Utils', () => {
it('should contain non-empty schema', ()=> {
schemaMgr.schema.should.be.an.Object();
schemaMgr.schema.should.be.not.empty;
schemaMgr.schema.should.be.not.empty();
});
it('should correctly init api url', ()=> {
@ -93,7 +89,7 @@ describe('Utils', () => {
it('should return empty array for non-specified tags', () => {
delete schemaMgr._schema.tags;
let tagsMap = schemaMgr.getTagsMap();
tagsMap.should.be.empty;
tagsMap.should.be.empty();
});
});
@ -155,8 +151,8 @@ describe('Utils', () => {
it('should map x-traitTag to empty methods list', () => {
let [, info] = entries[0];
info['x-traitTag'].should.be.true;
info.methods.should.be.empty;
info['x-traitTag'].should.be.true();
info.methods.should.be.empty();
});
it('methods for tag should contain valid pointer and summary', () => {
@ -238,13 +234,16 @@ describe('Utils', () => {
let deriveDefs = schemaMgr.findDerivedDefinitions('#/definitions/Pet');
deriveDefs.should.be.instanceof(Array);
deriveDefs.should.not.be.empty();
deriveDefs.should.be.deepEqual([{name: 'Cat', empty: false, $ref: '#/definitions/Cat'}, {name: 'Dog', empty: false, $ref: '#/definitions/Dog'}]);
deriveDefs.should.be.deepEqual([
{name: 'Cat', empty: false, $ref: '#/definitions/Cat'},
{name: 'Dog', empty: false, $ref: '#/definitions/Dog'}
]);
});
it('should return emtpy array for definitions that dont have discriminator', () => {
let deriveDefs = schemaMgr.findDerivedDefinitions('#/definitions/Order');
deriveDefs.should.be.instanceof(Array);
deriveDefs.should.be.empty;
deriveDefs.should.be.empty();
});
});
});

51
tslint.json Normal file
View File

@ -0,0 +1,51 @@
{
"rulesDirectory": ["node_modules/codelyzer"],
"rules": {
"class-name": true,
"curly": false,
"eofline": true,
"indent": ["spaces"],
"max-line-length": [true, 140],
"member-ordering": [true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-arg": true,
"no-construct": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-unreachable": true,
"no-use-before-declare": true,
"one-line": [true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [true, "single"],
"semicolon": true,
"trailing-comma": true,
"triple-equals": [true,
"allow-undefined-check"
],
"variable-name": false,
"directive-selector-name": [true, "camelCase"],
"component-selector-name": [true, "kebab-case"],
"directive-selector-type": [true, "attribute"],
"component-selector-type": [true, "element"],
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"no-input-rename": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true
}
}