Skip to content

Commit

Permalink
feat(okam-core): and ant mini program native component event handler …
Browse files Browse the repository at this point in the history
…adapter
  • Loading branch information
wuhy committed Nov 14, 2018
1 parent 6e52f6a commit 0efded5
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 0 deletions.
52 changes: 52 additions & 0 deletions packages/okam-core/src/ant/adapter/component.js
@@ -0,0 +1,52 @@
/**
* @file Fix ant native component to adapt okam event handler.
* @author sparklewhy@gmail.com
*/

'use strict';

import {normalizeEventArgs} from '../helper/triggerEvent';

function handleEvent(eventName, rawHandler, ...args) {
args.unshift(eventName);
normalizeEventArgs(this, args);
rawHandler.call(this, args[1]);
}

function normalizeEventHandlers(component) {
let props = component.props;
if (!props) {
return;
}

Object.keys(props).forEach(k => {
let handler = props[k];
let len = k.length;
if (typeof handler !== 'function' || len <= 2 || k.indexOf('on') !== 0) {
return;
}

// extract event name: onAbc => abc
let eventName = k.substr(3);
eventName = k.charAt(2).toLowerCase() + eventName;

props[k] = handleEvent.bind(component, eventName, handler);
});
}

/**
* Make the native ant component to adapt to the okam framework
*
* @param {Object} component the component to adapt
* @return {Object}
*/
export default function adaptOKAM(component) {
let didMount = component.didMount;
component.didMount = function () {
normalizeEventHandlers(this);
didMount && didMount.call(this);
};
return component;
}


160 changes: 160 additions & 0 deletions packages/okam-core/test/tasks/ant/adapter/component.spec.js
@@ -0,0 +1,160 @@
/**
* @file Ant component adapter test spec
* @author sparklewhy@gmail.com
*/

'use strict';

/* eslint-disable babel/new-cap */
/* eslint-disable fecs-min-vars-per-destructure */

import assert from 'assert';
import expect, {createSpy, spyOn} from 'expect';
import adapter from 'core/ant/adapter/component';

describe('Ant component adapter', () => {

it('should rewrite event handler', () => {
let clickSpy = createSpy(() => {}).andCallThrough();
let click2Spy = createSpy(() => {}).andCallThrough();
let component = {
props: {
a: 2,
onClick: clickSpy,
onClick2: click2Spy
}
};

adapter(component);

expect(Object.keys(component.props)).toEqual(['a', 'onClick', 'onClick2']);
assert(typeof component.didMount === 'function');
assert(component.props.onClick === clickSpy);
assert(component.props.onClick2 === click2Spy);

component.didMount();

expect(Object.keys(component.props)).toEqual(['a', 'onClick', 'onClick2']);
assert(component.props.onClick !== clickSpy);
assert(component.props.onClick2 !== click2Spy);

const spyPropClick = spyOn(component.props, 'onClick').andCallThrough();

component.props.onClick({a: 3});
expect(clickSpy).toHaveBeenCalled();
assert(clickSpy.calls.length === 1);
expect(clickSpy.calls[0].arguments).toEqual([{
type: 'click',
currentTarget: {dataset: {}, id: undefined},
target: {dataset: {}, id: undefined},
detail: {a: 3}
}]);
expect(clickSpy.calls[0].context).toBe(component);

expect(spyPropClick).toHaveBeenCalled();
assert(spyPropClick.calls.length === 1);
expect(spyPropClick.calls[0].arguments).toEqual([{a: 3}]);
expect(spyPropClick.calls[0].context).toBe(component.props);
});

it('should retain existed didMount hook when adapt the component', () => {
let clickSpy = createSpy(() => {}).andCallThrough();
let spyDidMount = createSpy(() => {}).andCallThrough();
let component = {
props: {
onClick: clickSpy
},
didMount: spyDidMount
};

adapter(component);

component.didMount();
assert(component.didMount !== spyDidMount);
expect(spyDidMount).toHaveBeenCalled();
assert(spyDidMount.calls.length === 1);
expect(spyDidMount.calls[0].context).toBe(component);

component.props.onClick({a: 3});
expect(clickSpy).toHaveBeenCalled();
assert(clickSpy.calls.length === 1);
expect(clickSpy.calls[0].arguments).toEqual([{
type: 'click',
currentTarget: {dataset: {}, id: undefined},
target: {dataset: {}, id: undefined},
detail: {a: 3}
}]);
expect(clickSpy.calls[0].context).toBe(component);
});

it.only('should do nothing when no props', function () {
let spyDidMount = createSpy(() => {}).andCallThrough();
let component = {
didMount: spyDidMount
};

adapter(component);

assert(component.props === undefined);
assert(component.didMount !== spyDidMount);

component.didMount();

expect(spyDidMount).toHaveBeenCalled();
assert(spyDidMount.calls.length === 1);
expect(spyDidMount.calls[0].context).toBe(component);
});

it('should ignore illegal event handler property', () => {
let myFuncSpy = createSpy(() => {}).andCallThrough();
let clickSpy = createSpy(() => {}).andCallThrough();
let myOnSpy = createSpy(() => {}).andCallThrough();
let onCSpy = createSpy(() => {}).andCallThrough();
let component = {
props: {
myFunc: myFuncSpy,
onclick: clickSpy,
on: myOnSpy,
onC: onCSpy
}
};

adapter(component);

expect(Object.keys(component.props)).toEqual(['myFunc', 'onclick', 'on', 'onC']);
assert(typeof component.didMount === 'function');
assert(component.props.myFunc === myFuncSpy);
assert(component.props.onclick === clickSpy);

component.didMount();

expect(Object.keys(component.props)).toEqual(['myFunc', 'onclick', 'on', 'onC']);
assert(component.props.onclick !== clickSpy);
assert(component.props.myFunc === myFuncSpy);
assert(component.props.on === myOnSpy);
assert(component.props.onC !== onCSpy);

component.props.onclick({a: 3});
expect(clickSpy).toHaveBeenCalled();
assert(clickSpy.calls.length === 1);
expect(clickSpy.calls[0].arguments).toEqual([{
type: 'click',
currentTarget: {dataset: {}, id: undefined},
target: {dataset: {}, id: undefined},
detail: {a: 3}
}]);
expect(clickSpy.calls[0].context).toBe(component);

component.props.onC({a: 3});
expect(onCSpy).toHaveBeenCalled();
assert(onCSpy.calls.length === 1);
expect(onCSpy.calls[0].arguments).toEqual([{
type: 'c',
currentTarget: {dataset: {}, id: undefined},
target: {dataset: {}, id: undefined},
detail: {a: 3}
}]);
expect(onCSpy.calls[0].context).toBe(component);
});

});

0 comments on commit 0efded5

Please sign in to comment.