Skip to content

Commit

Permalink
Merge pull request #7 from rico-projects/bugfix/createControllerChaining
Browse files Browse the repository at this point in the history
allow createController usage asynchronously without errors
  • Loading branch information
madmas committed Jan 29, 2019
2 parents a93de70 + 420479c commit 395ef46
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -37,6 +37,7 @@ npm-debug.log
yarn-error.log
testem.log
/typings
/test-reports

# System Files
.DS_Store
Expand Down
3 changes: 3 additions & 0 deletions .travis.yml
Expand Up @@ -27,6 +27,9 @@ before_install:

jobs:
include:
- stage: test
script:
- npm run test
- stage: build
script:
- npm run dist
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -15,6 +15,7 @@
"scripts": {
"build": "npm-install-peers && ng build rico-angular",
"build-watch": "npm-install-peers && ng build rico-angular --watch",
"test": "npm-install-peers && npx ng test --watch false",
"pack": "cd dist && npm pack",
"dist": "npm run build && npm run pack",
"start-int-test-server": "docker run -d -p 8085:8080 --rm --name rico-angular-int-server ricoprojects/integration:tomee-1.0.0-CR2",
Expand Down
10 changes: 6 additions & 4 deletions src/lib/controller-proxy.ts
Expand Up @@ -8,9 +8,11 @@ export class ControllerProxy {
private clientContext: any;
private internalModel: any;
private vanillaControllerProxy: any;
private name: string;

constructor(clientContext: any) {
constructor(name: string, clientContext: any) {
this.clientContext = clientContext;
this.name = name;
}

public get model(): any {
Expand All @@ -21,12 +23,12 @@ export class ControllerProxy {
return this.vanillaControllerProxy.invoke(name, params);
}

create(name: string): Promise<ControllerProxy> {
create(): Promise<ControllerProxy> {
const proxy = this;

return new Promise((resolve, reject) => {
proxy.clientContext.createController(name).then((controllerProxy) => {
ControllerProxy.LOGGER.debug('Controller proxy for', name, 'created', controllerProxy);
proxy.clientContext.createController(this.name).then((controllerProxy) => {
ControllerProxy.LOGGER.debug('Controller proxy for', this.name, 'created', controllerProxy);

proxy.vanillaControllerProxy = controllerProxy;
proxy.internalModel = controllerProxy.model;
Expand Down
107 changes: 107 additions & 0 deletions src/lib/rico-angular.service.spec.ts
Expand Up @@ -10,4 +10,111 @@ describe('RicoService', () => {
expect(service).toBeTruthy();
});

describe('createController', () => {

let controllerProxyMock;
let clientContextFactoryMock;
let clientContextMock;
let appRefMock;
let resolveFunc;

beforeEach(function() {
appRefMock = jasmine.createSpyObj('appRefMock', ['tick']);

controllerProxyMock = {
model: {}
}

const beanManagerMock = jasmine.createSpyObj('beanManagerMock', ['onAdded', 'onRemoved', 'onBeanUpdate', 'onArrayUpdate']);

clientContextMock = {
beanManager: beanManagerMock,
isConnected: false,
connect() {
this.isConnected = true;
return Promise.resolve();
},
createController(name: string) {
return new Promise(resolveFunc);
}
}

clientContextFactoryMock = {
create: function() {}
};
spyOn(clientContextFactoryMock, 'create').and.returnValue(clientContextMock);
});


it('create one controller', (done) => {
const service: RicoService = TestBed.get(RicoService);
spyOn(service, 'getClientContextFactory').and.returnValue(clientContextFactoryMock);
service.connect('http://www.foo.bar', appRefMock);

resolveFunc = (resolve, reject) => {
resolve(controllerProxyMock);
};

const promise = service.createController('bla');
promise.then(() => {
done();
});
});

it('create two controllers', (done) => {
const service: RicoService = TestBed.get(RicoService);
spyOn(service, 'getClientContextFactory').and.returnValue(clientContextFactoryMock);
service.connect('http://www.foo.bar', appRefMock);

resolveFunc = (resolve, reject) => {
resolve(controllerProxyMock);
};

const promiseA = service.createController('blaA');
const promiseB = service.createController('blaB');

let resolvedA = false;
promiseA.then(() => {
resolvedA = true;
});

promiseB.then(() => {
if (resolvedA) {
done();
} else {
done.fail();
}
});
});

it('create two controllers async', (done) => {
const service: RicoService = TestBed.get(RicoService);
spyOn(service, 'getClientContextFactory').and.returnValue(clientContextFactoryMock);
service.connect('http://www.foo.bar', appRefMock);

resolveFunc = (resolve, reject) => {
setTimeout(() => {
resolve(controllerProxyMock);
}, 1000);
};

const promiseA = service.createController('blaA');
const promiseB = service.createController('blaB');

let resolvedA = false;
promiseA.then(() => {
resolvedA = true;
});

promiseB.then(() => {
if (resolvedA) {
done();
} else {
done.fail();
}
});
});

})

});
39 changes: 37 additions & 2 deletions src/lib/rico-angular.service.ts
Expand Up @@ -12,9 +12,13 @@ export class RicoService {
private contextFactory: any;
private clientContext: any;
private modelMaintainer: ModelMaintainer;
private queue: Array<Function>;
private triggerResolveQueue: boolean;

constructor() {
RicoService.LOGGER.debug('RicoService created');
this.queue = [];
this.triggerResolveQueue = true;
}

connect(remotingEndpoint: string, appRef: ApplicationRef): Promise<any> {
Expand Down Expand Up @@ -53,10 +57,41 @@ export class RicoService {

createController(name: string): Promise<ControllerProxy> {
if (this.clientContext && this.clientContext.isConnected) {
const controllerProxy = new ControllerProxy(this.clientContext);
return controllerProxy.create(name);
return new Promise<ControllerProxy>((resolve, reject) => {
const controllerProxy = new ControllerProxy(name, this.clientContext);
this.addToQueue(controllerProxy, resolve, reject);
});
} else {
return Promise.reject('Cannot create controller. ClientContext not conntected');
}
}

private addToQueue(controllerProxy: ControllerProxy, resolve: Function, reject: Function) {
const promise = new Promise((res) => {
this.queue.push(res);
});

promise.then(() => {
controllerProxy.create().then((ctrlProxy) => {
resolve(ctrlProxy);
this.resolveFromQueue();
}).catch((error) => {
reject(error);
});
});

if (this.triggerResolveQueue) {
this.resolveFromQueue();
this.triggerResolveQueue = false;
}
}

private resolveFromQueue() {
if (this.queue.length > 0) {
const resolve = this.queue.shift();
resolve();
} else {
this.triggerResolveQueue = true;
}
}
}

0 comments on commit 395ef46

Please sign in to comment.