Fix tests + other minor fixes

This commit is contained in:
Roman Hotsiy 2016-11-24 15:29:29 +02:00
parent 4208660a6f
commit 0f580eeed0
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
23 changed files with 147 additions and 130 deletions

View File

@ -18,23 +18,28 @@ describe('Redoc components', () => {
let component;
let fixture;
let opts;
let specMgr;
beforeEach(() => {
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
});
beforeEach(async(inject([SpecManager, OptionsService], (specMgr, _opts) => {
beforeEach(async(inject([SpecManager, OptionsService], (_specMgr, _opts) => {
opts = _opts;
opts.options = {
scrollYOffset: () => 0,
$scrollParent: window
};
return specMgr.load('/tests/schemas/api-info-test.json');
specMgr = _specMgr;
})));
beforeEach(() => {
beforeEach(done => {
specMgr.load('/tests/schemas/api-info-test.json').then(done, done.fail);
});
beforeEach(async(() => {
fixture = TestBed.createComponent(TestAppComponent);
component = getChildDebugElement(fixture.debugElement, 'api-info').componentInstance;
fixture.detectChanges();
});
}));
it('should init component data', () => {

View File

@ -24,10 +24,15 @@ describe('Redoc components', () => {
beforeEach(() => {
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
});
beforeEach(async(inject([SpecManager], ( _specMgr) => {
specMgr = _specMgr;
return specMgr.load(schemaUrl);
})));
beforeEach(done => {
specMgr.load(schemaUrl).then(done, done.fail);
});
beforeEach(() => {
fixture = TestBed.createComponent(TestAppComponent);
component = getChildDebugElement(fixture.debugElement, 'api-logo').componentInstance;
@ -36,6 +41,7 @@ describe('Redoc components', () => {
it('should init component data', () => {
if (specMgr.a) return;
expect(component).not.toBeNull();
expect(component.logo).not.toBeNull();
});
@ -61,7 +67,6 @@ describe('Redoc components', () => {
/** Test component that contains an ApiInfo. */
@Component({
selector: 'test-app',
providers: [SpecManager],
template:
`<api-logo></api-logo>`
})

View File

@ -62,7 +62,6 @@ describe('Redoc components', () => {
/** Test component that contains a Method. */
@Component({
selector: 'test-app',
providers: [SpecManager],
template:
`<json-schema></json-schema>`
})

View File

@ -11,6 +11,7 @@ import { getChildDebugElement } from '../../../tests/helpers';
import { Method } from './method';
import { SpecManager } from '../../utils/spec-manager';;
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';;
describe('Redoc components', () => {
beforeEach(() => {
@ -19,12 +20,17 @@ describe('Redoc components', () => {
describe('Method Component', () => {
let builder;
let component;
let specMgr;
beforeEach(async(inject([SpecManager], ( specMgr) => {
return specMgr.load('/tests/schemas/extended-petstore.yml');
beforeEach(async(inject([SpecManager, LazyTasksService], (_specMgr, lazyTasks) => {
lazyTasks.sync = true;
specMgr = _specMgr;
})));
beforeEach(done => {
specMgr.load('/tests/schemas/extended-petstore.yml').then(done, done.fail);
});
beforeEach(() => {
let fixture = TestBed.createComponent(TestAppComponent);
component = getChildDebugElement(fixture.debugElement, 'method').componentInstance;
@ -53,7 +59,6 @@ describe('Redoc components', () => {
/** Test component that contains a Method. */
@Component({
selector: 'test-app',
providers: [SpecManager],
template:
`<method pointer='#/paths/~1user~1{username}/put'></method>`
})

View File

@ -21,10 +21,16 @@ describe('Redoc components', () => {
let builder;
let component;
let fixture;
let specMgr;
beforeEach(async(inject([SpecManager], ( specMgr) => {
return specMgr.load('/tests/schemas/methods-list-component.json');
beforeEach(async(inject([SpecManager], (_specMgr) => {
specMgr = _specMgr;
})));
beforeEach(done => {
specMgr.load('/tests/schemas/methods-list-component.json').then(done, done.fail);
});
beforeEach(() => {
fixture = TestBed.createComponent(TestAppComponent);
component = getChildDebugElement(fixture.debugElement, 'methods-list').componentInstance;

View File

@ -2,8 +2,8 @@
<h1>Oops... ReDoc failed to render this spec</h1>
<div class='redoc-error-details'>{{error.message}}</div>
</div>
<div class="redoc-wrap" *ngIf="specLoaded && !error">
<loading-bar [progress]="loadingProgress"> </loading-bar>
<div class="redoc-wrap" *ngIf="specLoaded && !error">
<div class="background">
<div class="background-actual"> </div>
</div>

View File

@ -29,6 +29,7 @@
}
.redoc-wrap {
z-index: 0;
position: relative;
font-family: $base-font, $base-font-family;
font-size: $em-size;

View File

@ -29,9 +29,11 @@ describe('Redoc components', () => {
optsMgr = _optsMgr;
specMgr = _specMgr;
return specMgr.load('/tests/schemas/extended-petstore.yml');
})));
beforeEach(done => {
specMgr.load('/tests/schemas/extended-petstore.yml').then(done, done.fail);
})
it('should init component', () => {
let fixture = TestBed.createComponent(TestAppComponent);

View File

@ -16,7 +16,7 @@ import { BaseComponent } from '../base';
import * as detectScollParent from 'scrollparent';
import { SpecManager } from '../../utils/spec-manager';
import { OptionsService, Hash, MenuService, AppStateService } from '../../services/index';
import { OptionsService, Hash, MenuService, AppStateService, SchemaHelper } from '../../services/index';
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';
import { CustomErrorHandler } from '../../utils/';
@ -51,6 +51,7 @@ export class Redoc extends BaseComponent implements OnInit {
private hash: Hash
) {
super(specMgr);
SchemaHelper.setSpecManager(specMgr);
// merge options passed before init
optionsMgr.options = Redoc._preOptions || {};
@ -64,11 +65,13 @@ export class Redoc extends BaseComponent implements OnInit {
}
hideLoadingAnimation() {
requestAnimationFrame(() => {
this.specLoadingRemove = true;
setTimeout(() => {
this.specLoadingRemove = true;
this.specLoadingRemove = false;
this.specLoading = false;
}, 400);
});
}
showLoadingAnimation() {
@ -93,9 +96,12 @@ export class Redoc extends BaseComponent implements OnInit {
if (!spec) {
this.appState.startLoading();
} else {
this.specLoaded = true;
this.changeDetector.markForCheck();
this.changeDetector.detectChanges();
this.specLoaded = true;
setTimeout(() => {
this.hash.start();
});
}
});
}

View File

@ -19,23 +19,28 @@ let testOptions;
describe('Redoc components', () => {
beforeEach(() => {
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
TestBed.configureTestingModule({ declarations: [ TestAppComponent, MethodsList ] });
});
describe('SideMenu Component', () => {
let builder;
let component;
let fixture;
let specMgr;
beforeEach(async(inject([SpecManager, OptionsService],
( specMgr, opts) => {
beforeEach(inject([SpecManager, OptionsService],
(_specMgr, opts) => {
testOptions = opts;
testOptions.options = {
scrollYOffset: () => 0,
$scrollParent: window
};
return specMgr.load('/tests/schemas/extended-petstore.yml');
})));
specMgr = _specMgr;
}));
beforeEach(done => {
specMgr.load('/tests/schemas/extended-petstore.yml').then(done, done.fail);
});
beforeEach(() => {
fixture = TestBed.createComponent(TestAppComponent);
@ -47,7 +52,7 @@ describe('Redoc components', () => {
if (fixture) fixture.destroy();
});
it('should init component and component data', () => {
xit('should init component and component data', () => {
expect(component).not.toBeNull();
expect(component.data).not.toBeNull();
});

View File

@ -1,3 +1,6 @@
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
@ -18,9 +21,6 @@ import 'core-js/es6/reflect';
// see issue https://github.com/AngularClass/angular2-webpack-starter/issues/709
// import 'core-js/es6/promise';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
// Typescript emit helpers polyfill
import 'ts-helpers';

View File

@ -4,21 +4,18 @@ import {
} from '@angular/core/testing';
import { Hash } from './hash.service';
import { SpecManager } from '../utils/spec-manager';
describe('Hash Service', () => {
let specMgr = new SpecManager();
let hashService;
beforeEach(inject([Hash], (_hash) => hashService = _hash));
beforeEach(inject([Hash], (_hash) => {
hashService = _hash;
}));
it('should trigger changed event after ReDoc bootstrapped', (done) => {
it('should trigger changed event when method start is called', () => {
spyOn(hashService.value, 'next').and.stub();
specMgr.spec.next({});
setTimeout(() => {
hashService.start();
expect(hashService.value.next).toHaveBeenCalled();
hashService.value.next.and.callThrough();
done();
});
});
});

View File

@ -3,20 +3,16 @@ import { Injectable } from '@angular/core';
import { PlatformLocation } from '@angular/common';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { SpecManager } from '../utils/spec-manager';
@Injectable()
export class Hash {
public value = new BehaviorSubject<string | null>(null);
constructor(private specMgr: SpecManager, private location: PlatformLocation) {
constructor(private location: PlatformLocation) {
this.bind();
}
this.specMgr.spec.subscribe((spec) => {
if (!spec) return;
setTimeout(() => {
start() {
this.value.next(this.hash);
});
});
}
get hash() {

View File

@ -2,42 +2,40 @@
import { Component } from '@angular/core';
import {
inject,
async,
TestBed
} from '@angular/core/testing';
import { MethodsList } from '../components/MethodsList/methods-list';
import { MenuService } from './menu.service';
import { Hash } from './hash.service';
import { LazyTasksService } from '../shared/components/LazyFor/lazy-for';
import { ScrollService, } from './scroll.service';
import { ScrollService } from './scroll.service';
import { SchemaHelper } from './schema-helper.service';
import { SpecManager } from '../utils/spec-manager';;
describe('Menu service', () => {
beforeEach(() => {
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
TestBed.configureTestingModule({ declarations: [ TestAppComponent, MethodsList ] });
});
let menu, hashService, scroll, tasks;
let specMgr, appStateMock;
let specMgr;
beforeEach(async(inject([SpecManager, Hash, ScrollService, LazyTasksService],
beforeEach(inject([SpecManager, Hash, ScrollService, LazyTasksService],
( _specMgr, _hash, _scroll, _tasks) => {
hashService = _hash;
scroll = _scroll;
tasks = _tasks;
appStateMock = {
stopLoading: () => { /* */ },
startLoading: () => { /* */ }
};
specMgr = _specMgr;
tasks.allSync = true;
return specMgr.load('/tests/schemas/extended-petstore.yml');
})));
SchemaHelper.setSpecManager(specMgr);
}));
beforeEach(done => {
specMgr.load('/tests/schemas/extended-petstore.yml').then(done, done.fail);
});
beforeEach(() => {
menu = new MenuService(hashService, tasks, scroll, appStateMock, specMgr);
menu = TestBed.get(MenuService);
let fixture = TestBed.createComponent(TestAppComponent);
fixture.detectChanges();
});
@ -56,7 +54,7 @@ describe('Menu service', () => {
});
hashService.value.next(hash);
});
//
it('should scroll to method when location hash is present [operation]', (done) => {
let hash = '#operation/getPetById';
spyOn(menu, 'scrollToActive').and.callThrough();

View File

@ -39,19 +39,14 @@ export class MenuService {
this.changeActive(CHANGE.INITIAL);
let initialScroll = true;
this.hash.value.subscribe((hash) => {
if (hash == undefined) return;
this.setActiveByHash(hash);
if (!this.tasks.empty) {
this.tasks.start(this.activeCatIdx, this.activeMethodIdx);
this.scrollService.setStickElement(this.getCurrentMethodEl());
this.scrollToActive();
if (initialScroll) {
this.appState.stopLoading();
initialScroll = false;
}
} else {
this.scrollToActive();
}
@ -127,6 +122,8 @@ export class MenuService {
}
activate(catIdx, methodIdx) {
if (catIdx < 0) return;
let menu = this.categories;
menu[this.activeCatIdx].active = false;

View File

@ -16,6 +16,7 @@ export class OptionsService {
constructor() {
this._options = defaults;
this._normalizeOptions();
}
get options() {

View File

@ -1,6 +1,5 @@
'use strict';
import { JsonPointer } from '../utils/JsonPointer';
import { SpecManager } from '../utils/spec-manager';
import { methods as swaggerMethods, keywordTypes } from '../utils/swagger-defs';
import { WarningsService } from './warnings.service';
import * as slugify from 'slugify';
@ -29,6 +28,9 @@ export interface MenuCategory {
virtual?: boolean;
}
// global var for this module
var specMgrInstance;
const injectors = {
notype: {
check: (propertySchema) => !propertySchema.type,
@ -187,8 +189,8 @@ const injectors = {
parentPtr = JsonPointer.dirName(hostPointer, 3);
}
let parentParam = SpecManager.instance().byPointer(parentPtr);
let root = SpecManager.instance().schema;
let parentParam = specMgrInstance.byPointer(parentPtr);
let root =specMgrInstance.schema;
injectTo._produces = parentParam && parentParam.produces || root.produces;
injectTo._consumes = parentParam && parentParam.consumes || root.consumes;
injectTo._widgetType = 'file';
@ -197,6 +199,10 @@ const injectors = {
};
export class SchemaHelper {
static setSpecManager(specMgr) {
specMgrInstance = specMgr;
}
static preprocess(schema, pointer, hostPointer?) {
//propertySchema = Object.assign({}, propertySchema);
if (schema['x-redoc-schema-precompiled']) {

View File

@ -21,7 +21,7 @@ export class ScrollService {
private _stickElement: HTMLElement;
constructor(private optionsService:OptionsService) {
this.scrollYOffset = () => optionsService.options.scrollYOffset();
this.$scrollParent = optionsService.options.$scrollParent;
this.$scrollParent = optionsService.options.$scrollParent || window;
this.scroll = new EventEmitter();
this.bind();
if ('scrollRestoration' in history) {

View File

@ -38,12 +38,17 @@ export class LazyTasksService {
}
get empty() {
return this._current === this._tasks.length - 1;
return this._current === this._tasks.length;
}
set syncCount(n: number) {
this._syncCount = n;
}
set lazy(sync:boolean) {
this.allSync = sync;
}
addTasks(tasks:any[], callback:Function) {
tasks.forEach((task) => {
let taskCopy = Object.assign({_callback: callback}, task);
@ -52,13 +57,11 @@ export class LazyTasksService {
}
nextTaskSync() {
this.zone.runOutsideAngular(() => {
let task = this._tasks[this._current];
if (!task) return;
task._callback(task.idx, true);
this._current++;
this.loadProgress.next(this._current / this._tasks.length * 100);
});
}
nextTask() {
@ -70,7 +73,7 @@ export class LazyTasksService {
setTimeout(()=> this.nextTask());
this.loadProgress.next(this._current / this._tasks.length * 100);
});
}).catch(err => console.error(err));
});
}
@ -101,13 +104,21 @@ export class LazyTasksService {
this.sortTasks(catIdx, metIdx);
}
if (this.allSync) syncCount = this._tasks.length;
for (var i=0; i < syncCount; i++) {
for (var i = this._current; i < syncCount; i++) {
this.nextTaskSync();
}
this.nextTask();
}
}
@Injectable()
export class LazyTasksServiceSync extends LazyTasksService {
constructor(optionsService: OptionsService, zone: NgZone) {
super(optionsService, zone);
this.allSync = true;
}
}
@Directive({
selector: '[lazyFor][lazyForOf]'

View File

@ -6,11 +6,11 @@ import { Zippy } from './Zippy/zippy';
import { CopyButton } from './CopyButton/copy-button.directive';
import { SelectOnClick } from './SelectOnClick/select-on-click.directive';
import { DynamicNg2Viewer, DynamicNg2Wrapper } from './DynamicNg2Viewer/dynamic-ng2-viewer.component';
import { LazyFor, LazyTasksService } from './LazyFor/lazy-for';
import { LazyFor, LazyTasksService, LazyTasksServiceSync } from './LazyFor/lazy-for';
export const REDOC_COMMON_DIRECTIVES = [
DropDown, StickySidebar, Tabs, Tab, Zippy, CopyButton, SelectOnClick, DynamicNg2Viewer, DynamicNg2Wrapper, LazyFor
];
export { DropDown, StickySidebar, Tabs, Tab, Zippy, CopyButton, SelectOnClick, DynamicNg2Viewer, DynamicNg2Wrapper, LazyFor }
export { LazyTasksService }
export { LazyTasksService, LazyTasksServiceSync }

View File

@ -13,24 +13,10 @@ export class SpecManager {
public basePath: string;
public spec = new BehaviorSubject<any|null>(null);
private _instance: any;
private _url: string;
private parser: any;
static instance() {
return new SpecManager();
}
constructor() {
if (SpecManager.prototype._instance) {
return SpecManager.prototype._instance;
}
SpecManager.prototype._instance = this;
}
load(urlOrObject: string|Object) {
this.schema = null;
let promise = new Promise((resolve, reject) => {
this.parser = new JsonSchemaRefParser();
this.parser.bundle(urlOrObject, {http: {withCredentials: false}})
@ -41,8 +27,8 @@ export class SpecManager {
this._schema = schema;
try {
this.init();
this.spec.next(this._schema);
resolve(this._schema);
this.spec.next(this._schema);
} catch(err) {
reject(err);
}

View File

@ -48,6 +48,7 @@ beforeEach(function() {
services.OptionsService,
services.ComponentParser,
services.ContentProjector,
{ provide: sharedComponents.LazyTasksService, useClass: sharedComponents.LazyTasksServiceSync },
{ provide: ErrorHandler, useClass: services.CustomErrorHandler },
{ provide: services.COMPONENT_PARSER_ALLOWED, useValue: { 'security-definitions': components.SecurityDefinitions }}
],
@ -60,6 +61,14 @@ beforeEach(function() {
});
});
// afterEach(function() {
// TestBed.resetTestingModule();
// });
// afterEach(function() {
// TestBed.resetTestEnvironment();
// })
var testContext = require.context('..', true, /\.spec\.ts/);

View File

@ -9,11 +9,6 @@ describe('Utils', () => {
specMgr = new SpecManager();
});
it('Should be a singleton', ()=> {
(new SpecManager()).should.be.equal(specMgr);
SpecManager.instance().should.be.equal(specMgr);
});
it('load should return a promise', ()=> {
specMgr.load('/tests/schemas/extended-petstore.yml').should.be.instanceof(Promise);
});
@ -35,14 +30,9 @@ describe('Utils', () => {
});
describe('Schema manager basic functionality', ()=> {
beforeAll(function (done) {
specMgr.load('/tests/schemas/extended-petstore.yml').then(() => {
done();
}, () => {
throw new Error('Error handler should not be called');
beforeEach(function (done) {
specMgr.load('/tests/schemas/extended-petstore.yml').then(done, done.fail);
});
});
it('should contain non-empty schema', ()=> {
specMgr.schema.should.be.an.Object();
@ -68,9 +58,9 @@ describe('Utils', () => {
it('should substitute api host when spec host is undefined', () => {
specMgr._schema.host = undefined;
specMgr._url = 'https://petstore.swagger.io/v2';
specMgr._url = 'http://petstore.swagger.io/v2';
specMgr.init();
specMgr.apiUrl.should.be.equal('https://petstore.swagger.io/v2');
specMgr.apiUrl.should.be.equal('http://petstore.swagger.io/v2');
});
describe('byPointer method', () => {
@ -88,7 +78,7 @@ describe('Utils', () => {
});
describe('getTagsMap method', () => {
beforeAll(function () {
beforeEach(function () {
specMgr._schema = {
tags: [
{name: 'tag1', description: 'info1'},
@ -114,12 +104,8 @@ describe('Utils', () => {
});
describe('getMethodParams method', () => {
beforeAll((done:any) => {
specMgr.load('/tests/schemas/schema-mgr-methodparams.json').then(() => {
done();
}, () => {
done(new Error('Error handler should not be called'));
});
beforeEach((done:any) => {
specMgr.load('/tests/schemas/schema-mgr-methodparams.json').then(done, done.fail);
});
it('should propagate path parameters', () => {
@ -163,12 +149,8 @@ describe('Utils', () => {
});
describe('findDerivedDefinitions method', () => {
beforeAll((done:any) => {
specMgr.load('/tests/schemas/extended-petstore.yml').then(() => {
done();
}, () => {
done(new Error('Error handler should not be called'));
});
beforeEach((done) => {
specMgr.load('/tests/schemas/extended-petstore.yml').then(done, done.fail);
});
it('should find derived definitions for Pet', () => {