Skip to content

Commit 1b98aca

Browse files
committed
Updates
New Plugins Android Exoplayer ApplePay DNS Extended Device Information Google Play Games Services InAppPurchase2 Index App Content Keychain TouchId UID Updated Android Fingerprint Auth Android Full Screen Android Permissions App Availability App Minimize App Update Badge BLE CodePush Contacts File FTP Globalization Media NativeGeocoder NativeKeyboard Push Stripe ThemeableBrowser WheelSelector Zeroconf
1 parent 9d36e10 commit 1b98aca

File tree

36 files changed

+1435
-197
lines changed

36 files changed

+1435
-197
lines changed

src/@ionic-native-mocks/core/decorators.spec.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'core-js';
22
import { Plugin, Cordova, CordovaProperty, CordovaCheck, CordovaInstance, InstanceProperty } from './decorators';
33
import { IonicNativePlugin } from './ionic-native-plugin';
44
import { ERR_CORDOVA_NOT_AVAILABLE, ERR_PLUGIN_NOT_INSTALLED } from './plugin';
5+
import { Observable } from 'rxjs/Observable';
56

67
declare const window: any;
78

@@ -47,6 +48,17 @@ class TestPlugin extends IonicNativePlugin {
4748
return new TestObject(TestPlugin.getPlugin().create());
4849
}
4950

51+
@Cordova({
52+
destruct: true
53+
})
54+
destructPromise(): Promise<any> { return; }
55+
56+
@Cordova({
57+
destruct: true,
58+
observable: true
59+
})
60+
destructObservable(): Observable<any> { return; }
61+
5062
}
5163

5264
function definePlugin() {
@@ -59,7 +71,9 @@ function definePlugin() {
5971
this.ping = (success: Function, error: Function) => success('pong');
6072
this.name = 'John Smith';
6173
return this;
62-
}
74+
},
75+
destructPromise: (success: Function) => success('hello', 'world'),
76+
destructObservable: (success: Function) => success('hello', 'world')
6377
};
6478
}
6579

@@ -177,6 +191,30 @@ describe('Regular Decorators', () => {
177191

178192
});
179193

194+
describe('CordovaOptions', () => {
195+
196+
describe('destruct', () => {
197+
198+
it('should destruct values returned by a Promise', (done) => {
199+
plugin.destructPromise()
200+
.then((args: any[]) => {
201+
expect(args).toEqual(['hello', 'world']);
202+
done();
203+
});
204+
});
205+
206+
it('should destruct values returned by an Observable', (done) => {
207+
plugin.destructObservable()
208+
.subscribe((args: any[]) => {
209+
expect(args).toEqual(['hello', 'world']);
210+
done();
211+
});
212+
});
213+
214+
});
215+
216+
});
217+
180218
});
181219

182220
describe('Instance Decorators', () => {

src/@ionic-native-mocks/core/decorators.ts

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export interface PluginConfig {
3737
}
3838

3939
export interface CordovaOptions {
40+
destruct?: boolean;
4041
/**
4142
* Set to true if the wrapped method is a sync function
4243
*/
@@ -104,17 +105,6 @@ export interface CordovaCheckOptions {
104105
observable?: boolean;
105106
}
106107

107-
export interface CordovaFiniteObservableOptions extends CordovaOptions {
108-
/**
109-
* Function that gets a result returned from plugin's success callback, and decides whether it is last value and observable should complete.
110-
*/
111-
resultFinalPredicate?: (result: any) => boolean;
112-
/**
113-
* Function that gets called after resultFinalPredicate, and removes service data that indicates end of stream from the result.
114-
*/
115-
resultTransform?: (result: any) => any;
116-
}
117-
118108
/**
119109
* @private
120110
*/
@@ -166,7 +156,6 @@ export function CordovaCheck(opts: CordovaCheckOptions = {}) {
166156
};
167157
}
168158

169-
170159
/**
171160
* @private
172161
*
@@ -252,7 +241,7 @@ export function Cordova(opts: CordovaOptions = {}) {
252241
*
253242
* Wrap an instance method
254243
*/
255-
export function CordovaInstance(opts: any = {}) {
244+
export function CordovaInstance(opts: CordovaOptions = {}) {
256245
return (target: Object, methodName: string) => {
257246
return {
258247
value: function(...args: any[]) {
@@ -322,39 +311,3 @@ export function CordovaFunctionOverride(opts: any = {}) {
322311
};
323312
}
324313

325-
326-
/**
327-
* @private
328-
*
329-
* Wraps method that returns an observable that can be completed. Provided opts.resultFinalPredicate dictates when the observable completes.
330-
*
331-
*/
332-
export function CordovaFiniteObservable(opts: CordovaFiniteObservableOptions = {}) {
333-
if (opts.observable === false) {
334-
throw new Error('CordovaFiniteObservable decorator can only be used on methods that returns observable. Please provide correct option.');
335-
}
336-
opts.observable = true;
337-
return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor<any>) => {
338-
return {
339-
value: function(...args: any[]) {
340-
let wrappedObservable: Observable<any> = wrap(this, methodName, opts).apply(this, args);
341-
return new Observable<any>((observer) => {
342-
let wrappedSubscription = wrappedObservable.subscribe({
343-
next: (x) => {
344-
observer.next(opts.resultTransform ? opts.resultTransform(x) : x);
345-
if (opts.resultFinalPredicate && opts.resultFinalPredicate(x)) {
346-
observer.complete();
347-
}
348-
},
349-
error: (err) => { observer.error(err); },
350-
complete: () => { observer.complete(); }
351-
});
352-
return () => {
353-
wrappedSubscription.unsubscribe();
354-
};
355-
});
356-
},
357-
enumerable: true
358-
};
359-
};
360-
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// This is to verify that new (FileTransfer.getPlugin)() works
2+
3+
import { Plugin, CordovaInstance } from './decorators';
4+
import { checkAvailability } from './plugin';
5+
import { IonicNativePlugin } from './ionic-native-plugin';
6+
7+
class FT {
8+
hello(): string {
9+
return 'world';
10+
}
11+
}
12+
13+
(window as any).FileTransfer = () => new FT();
14+
15+
@Plugin({
16+
plugin: 'cordova-plugin-file-transfer',
17+
pluginRef: 'FileTransfer',
18+
repo: '',
19+
pluginName: 'FileTransfer'
20+
})
21+
export class FileTransfer extends IonicNativePlugin {
22+
create(): FileTransferObject {
23+
let instance: any;
24+
if (checkAvailability(FileTransfer.getPluginRef(), null, FileTransfer.getPluginName()) === true) {
25+
instance = new (FileTransfer.getPlugin())();
26+
}
27+
return new FileTransferObject(instance);
28+
}
29+
}
30+
31+
export class FileTransferObject {
32+
33+
constructor(public _objectInstance: any) {
34+
console.info('Creating a new FileTransferObject with instance: ', _objectInstance);
35+
}
36+
37+
@CordovaInstance({ sync: true })
38+
hello(): string { return; }
39+
40+
}
41+
42+
describe('Mock FileTransfer Plugin', () => {
43+
44+
let plugin: FileTransfer,
45+
instance: FileTransferObject;
46+
47+
beforeAll(() => {
48+
plugin = new FileTransfer();
49+
instance = plugin.create();
50+
});
51+
52+
it('should create a new FileTransfer plugin instance', () => {
53+
expect(plugin instanceof FileTransfer).toBeTruthy();
54+
});
55+
56+
it('should create new FileTransferObject instance', () => {
57+
expect(instance instanceof FileTransferObject).toBeTruthy();
58+
});
59+
60+
it('FileTransferObject instance should have _objectInstance property', () => {
61+
expect(instance._objectInstance).toBeDefined();
62+
});
63+
64+
it('FileTransferObject.hello should return world', () => {
65+
console.info('instance hello is', instance.hello());
66+
expect(instance.hello()).toEqual('world');
67+
});
68+
69+
});

src/@ionic-native-mocks/core/plugin.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,11 @@ function callCordovaPlugin(pluginObj: any, methodName: string, args: any[], opts
136136
function wrapPromise(pluginObj: any, methodName: string, args: any[], opts: any = {}) {
137137
let pluginResult: any, rej: Function;
138138
const p = getPromise((resolve: Function, reject: Function) => {
139-
pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject);
139+
if (opts.destruct) {
140+
pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, (...args: any[]) => resolve(args), (...args: any[]) => reject(args));
141+
} else {
142+
pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, resolve, reject);
143+
}
140144
rej = reject;
141145
});
142146
// Angular throws an error on unhandled rejection, but in this case we have already printed
@@ -166,7 +170,14 @@ function wrapOtherPromise(pluginObj: any, methodName: string, args: any[], opts:
166170

167171
function wrapObservable(pluginObj: any, methodName: string, args: any[], opts: any = {}) {
168172
return new Observable(observer => {
169-
let pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer));
173+
let pluginResult;
174+
175+
if (opts.destruct) {
176+
pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, (...args: any[]) => observer.next(args), (...args: any[]) => observer.error(args));
177+
} else {
178+
pluginResult = callCordovaPlugin(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer));
179+
}
180+
170181
if (pluginResult && pluginResult.error) {
171182
observer.error(pluginResult.error);
172183
observer.complete();
@@ -219,7 +230,7 @@ export function wrapEventObservable(event: string, element: any = window): Obser
219230
export function overrideFunction(pluginObj: any, methodName: string, args: any[], opts: any = {}): Observable<any> {
220231
return new Observable(observer => {
221232

222-
const availabilityCheck = checkAvailability(pluginObj, methodName);
233+
const availabilityCheck = checkAvailability(pluginObj, null, pluginObj.constructor.getPluginName());
223234

224235
if (availabilityCheck === true) {
225236
const pluginInstance = getPlugin(pluginObj.constructor.getPluginRef());
@@ -266,7 +277,14 @@ export function wrapInstance(pluginObj: any, methodName: string, opts: any = {})
266277
} else if (opts.observable) {
267278

268279
return new Observable(observer => {
269-
let pluginResult = callInstance(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer));
280+
281+
let pluginResult;
282+
283+
if (opts.destruct) {
284+
pluginResult = callInstance(pluginObj, methodName, args, opts, (...args: any[]) => observer.next(args), (...args: any[]) => observer.error(args));
285+
} else {
286+
pluginResult = callInstance(pluginObj, methodName, args, opts, observer.next.bind(observer), observer.error.bind(observer));
287+
}
270288

271289
if (pluginResult && pluginResult.error) {
272290
observer.error(pluginResult.error);
@@ -287,9 +305,13 @@ export function wrapInstance(pluginObj: any, methodName: string, opts: any = {})
287305
});
288306

289307
} else if (opts.otherPromise) {
290-
291308
return getPromise((resolve: Function, reject: Function) => {
292-
let result = callInstance(pluginObj, methodName, args, opts, resolve, reject);
309+
let result;
310+
if (opts.destruct) {
311+
result = callInstance(pluginObj, methodName, args, opts, (...args: any[]) => resolve(args), (...args: any[]) => reject(args));
312+
} else {
313+
result = callInstance(pluginObj, methodName, args, opts, resolve, reject);
314+
}
293315
if (result && !!result.then) {
294316
result.then(resolve, reject);
295317
} else {
@@ -298,8 +320,24 @@ export function wrapInstance(pluginObj: any, methodName: string, opts: any = {})
298320
});
299321

300322
} else {
323+
let pluginResult: any, rej: Function;
324+
const p = getPromise((resolve: Function, reject: Function) => {
325+
if (opts.destruct) {
326+
pluginResult = callInstance(pluginObj, methodName, args, opts, (...args: any[]) => resolve(args), (...args: any[]) => reject(args));
327+
} else {
328+
pluginResult = callInstance(pluginObj, methodName, args, opts, resolve, reject);
329+
}
330+
rej = reject;
331+
});
332+
// Angular throws an error on unhandled rejection, but in this case we have already printed
333+
// a warning that Cordova is undefined or the plugin is uninstalled, so there is no reason
334+
// to error
335+
if (pluginResult && pluginResult.error) {
336+
p.catch(() => { });
337+
typeof rej === 'function' && rej(pluginResult.error);
338+
}
339+
return p;
301340

302-
return getPromise((resolve: Function, reject: Function) => callInstance(pluginObj, methodName, args, opts, resolve, reject));
303341

304342
}
305343
};

0 commit comments

Comments
 (0)