Match-id-55336dea881a38bb66f9be8c8033d4c390a8c849

This commit is contained in:
* 2022-03-25 18:35:34 +08:00 committed by *
commit eaa13a6ad1
6 changed files with 594 additions and 0 deletions

View File

@ -0,0 +1,131 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
import * as LogUtils from '../jest/logUtils';
import * as TestUtils from '../jest/testUtils';
describe('事件', () => {
it('根节点挂载全量事件', () => {
const App = () => {
return <div />;
}
Horizon.render(<App />, container);
console.log(TestUtils.getEventListeners(container));
})
it('事件捕获与冒泡', () => {
const App = () => {
return (
<>
<div onClickCapture={() => LogUtils.log('div capture')} onClick={() => LogUtils.log('div bubble')}>
<p onClickCapture={() => LogUtils.log('p capture')} onClick={() => LogUtils.log('p bubble')}>
<button onClickCapture={() => LogUtils.log('btn capture')} onClick={() => LogUtils.log('btn bubble')} />
</p>
</div>
</>
);
}
Horizon.render(<App />, container);
const a = container.querySelector('button');
a.click();
expect(LogUtils.getAndClear()).toEqual([
// 从外到内先捕获再冒泡
'div capture',
'p capture',
'btn capture',
'btn bubble',
'p bubble',
'div bubble'
]);
})
it('returns 0', () => {
let keyCode = null;
const node = Horizon.render(
<input
onKeyPress={e => {
keyCode = e.keyCode;
}}
/>,
container,
);
node.dispatchEvent(
new KeyboardEvent('keypress', {
keyCode: 65,
bubbles: true,
cancelable: true,
}),
);
expect(keyCode).toBe(65);
});
it('阻止事件冒泡', () => {
const App = () => {
return (
<>
<div onClickCapture={() => LogUtils.log('div capture')} onClick={() => LogUtils.log('div bubble')}>
<p onClickCapture={() => LogUtils.log('p capture')} onClick={() => LogUtils.log('p bubble')}>
<button onClickCapture={() => LogUtils.log('btn capture')} onClick={(e) => TestUtils.stopBubbleOrCapture(e, 'btn bubble')} />
</p>
</div>
</>
);
}
Horizon.render(<App />, container);
container.querySelector('button').click();
expect(LogUtils.getAndClear()).toEqual([
// 到button时停止冒泡
'div capture',
'p capture',
'btn capture',
'btn bubble'
]);
})
it('阻止事件捕获', () => {
const App = () => {
return (
<>
<div onClickCapture={(e) => TestUtils.stopBubbleOrCapture(e, 'div capture')} onClick={() => LogUtils.log('div bubble')}>
<p onClickCapture={() => LogUtils.log('p capture')} onClick={() => LogUtils.log('p bubble')}>
<button onClickCapture={() => LogUtils.log('btn capture')} onClick={() => LogUtils.log('btn bubble')} />
</p>
</div>
</>
);
}
Horizon.render(<App />, container);
container.querySelector('button').click();
expect(LogUtils.getAndClear()).toEqual([
// 阻止捕获,不再继续向下执行
'div capture'
]);
})
it('阻止原生事件冒泡', () => {
const App = () => {
return (
<div>
<p>
<button />
</p>
</div>
);
}
Horizon.render(<App />, container);
container.querySelector('div').addEventListener('click', () => {
LogUtils.log('div bubble');
}, false);
container.querySelector('p').addEventListener('click', () => {
LogUtils.log('p bubble');
}, false);
container.querySelector('button').addEventListener('click', (e) => {
LogUtils.log('btn bubble');
e.stopPropagation();
}, false);
container.querySelector('button').click();
expect(LogUtils.getAndClear()).toEqual([
'btn bubble'
]);
})
})

View File

@ -0,0 +1,46 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
import * as LogUtils from '../jest/logUtils';
import { act } from '../jest/customMatcher';
describe('合成焦点事件', () => {
it('onFocus', () => {
const realNode = Horizon.render(
<input
onFocus={event => LogUtils.log(`onFocus: ${event.type}`)}
onFocusCapture={event => LogUtils.log(`onFocusCapture: ${event.type}`)}
/>, container);
realNode.dispatchEvent(
new FocusEvent('focusin', {
bubbles: true,
cancelable: false,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onFocusCapture: focus',
'onFocus: focus',
]);
});
it('onBlur', () => {
const realNode = Horizon.render(
<input
onBlur={event => LogUtils.log(`onBlur: ${event.type}`)}
onBlurCapture={event => LogUtils.log(`onBlurCapture: ${event.type}`)}
/>, container);
realNode.dispatchEvent(
new FocusEvent('focusout', {
bubbles: true,
cancelable: false,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onBlurCapture: blur',
'onBlur: blur',
]);
})
})

View File

@ -0,0 +1,179 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
import * as LogUtils from '../jest/logUtils';
describe('Keyboard Event', () => {
it('keydown,keypress,keyup的keycode,charcode', () => {
const node = Horizon.render(
<input
onKeyUp={(e) => {
LogUtils.log('onKeyUp: keycode: ' + e.keyCode + ',charcode: ' + e.charCode);
}}
onKeyDown={(e) => {
LogUtils.log('onKeyDown: keycode: ' + e.keyCode + ',charcode: ' + e.charCode)
}}
/>,
container,
);
node.dispatchEvent(
new KeyboardEvent('keydown', {
keyCode: 50,
code: 'Digit2',
bubbles: true,
cancelable: true,
}),
);
node.dispatchEvent(
new KeyboardEvent('keyup', {
keyCode: 50,
code: 'Digit2',
bubbles: true,
cancelable: true,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onKeyDown: keycode: 50,charcode: 0',
'onKeyUp: keycode: 50,charcode: 0'
]);
});
it('keypress的keycode,charcode', () => {
const node = Horizon.render(
<input
onKeyPress={(e) => {
LogUtils.log('onKeyPress: keycode: ' + e.keyCode + ',charcode: ' + e.charCode);
}}
/>,
container,
);
node.dispatchEvent(
new KeyboardEvent('keypress', {
charCode: 50,
code: 'Digit2',
bubbles: true,
cancelable: true,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onKeyPress: keycode: 0,charcode: 50'
]);
});
it('当charcode为13,且不设置keycode的时候', () => {
const node = Horizon.render(
<input
onKeyPress={(e) => {
LogUtils.log('onKeyPress: keycode: ' + e.keyCode + ',charcode: ' + e.charCode);
}}
/>,
container,
);
node.dispatchEvent(
new KeyboardEvent('keypress', {
charCode: 13,
bubbles: true,
cancelable: true,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onKeyPress: keycode: 0,charcode: 13'
]);
});
it('keydown,keypress,keyup的code', () => {
const node = Horizon.render(
<input
onKeyUp={(e) => {
LogUtils.log('onKeyUp: code: ' + e.code);
}}
onKeyPress={(e) => {
LogUtils.log('onKeyPress: code: ' + e.code);
}}
onKeyDown={(e) => {
LogUtils.log('onKeyDown: code: ' + e.code);
}}
/>,
container,
);
node.dispatchEvent(
new KeyboardEvent('keydown', {
code: 'Digit2',
bubbles: true,
cancelable: true,
}),
);
node.dispatchEvent(
new KeyboardEvent('keypress', {
keyCode: 50,
code: 'Digit2',
bubbles: true,
cancelable: true,
}),
);
node.dispatchEvent(
new KeyboardEvent('keyup', {
code: 'Digit2',
bubbles: true,
cancelable: true,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onKeyDown: code: Digit2',
'onKeyPress: code: Digit2',
'onKeyUp: code: Digit2'
]);
});
it('可以执行preventDefault和 stopPropagation', () => {
const keyboardProcessing = e => {
expect(e.isDefaultPrevented()).toBe(false);
e.preventDefault();
expect(e.isDefaultPrevented()).toBe(true);
expect(e.isPropagationStopped()).toBe(false);
e.stopPropagation();
expect(e.isPropagationStopped()).toBe(true);
LogUtils.log(e.type + ' handle');
};
const div = Horizon.render(
<div
onKeyDown={keyboardProcessing}
onKeyUp={keyboardProcessing}
onKeyPress={keyboardProcessing}
/>,
container,
);
div.dispatchEvent(
new KeyboardEvent('keydown', {
keyCode: 40,
bubbles: true,
cancelable: true,
}),
);
div.dispatchEvent(
new KeyboardEvent('keyup', {
keyCode: 40,
bubbles: true,
cancelable: true,
}),
);
div.dispatchEvent(
new KeyboardEvent('keypress', {
charCode: 40,
bubbles: true,
cancelable: true,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'keydown handle',
'keyup handle',
'keypress handle'
]);
});
});

View File

@ -0,0 +1,160 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
import * as LogUtils from '../jest/logUtils';
describe('MouseEvent Test', () => {
describe('onClick Test', () => {
it('绑定this', () => {
class App extends Horizon.Component {
constructor(props) {
super(props);
this.state = {
num: this.props.num,
price: this.props.price
};
}
setNum() {
this.setState(
{
num: this.state.num + 1
}
)
}
setPrice = (e) => {
this.setState(
{
num: this.state.price + 1
}
)
}
render() {
return (
<>
<p>{this.state.num}</p>
<p id="p">{this.state.price}</p>
<button onClick={this.setNum.bind(this)} >button</button>
<button id="btn" onClick={() => this.setPrice()} >button</button>
</>
);
}
}
Horizon.render(<App num={0} price={100} />, container);
expect(container.querySelector('p').innerHTML).toBe('0');
expect(container.querySelector('#p').innerHTML).toBe('100');
// 点击按钮触发num加1
container.querySelector('button').click();
expect(container.querySelector('p').innerHTML).toBe('1');
container.querySelector('#btn').click();
expect(container.querySelector('p').innerHTML).toBe('101');
});
it('点击触发', () => {
const handleClick = jest.fn();
Horizon.render(<button onClick={handleClick}>Click Me</button>, container)
container.querySelector('button').click();
expect(handleClick).toHaveBeenCalledTimes(1);
for (let i = 0; i < 5; i++) {
container.querySelector('button').click();
}
expect(handleClick).toHaveBeenCalledTimes(6);
})
})
const test = (name, config) => {
const node = Horizon.render(config, container);
let event = new MouseEvent(name, {
relatedTarget: null,
bubbles: true,
screenX: 1
});
node.dispatchEvent(event);
expect(LogUtils.getAndClear()).toEqual([
`${name} capture`,
`${name} bubble`
]);
event = new MouseEvent(name, {
relatedTarget: null,
bubbles: true,
screenX: 2
});
node.dispatchEvent(event);
// 再次触发新事件
expect(LogUtils.getAndClear()).toEqual([
`${name} capture`,
`${name} bubble`
]);
}
describe('合成鼠标事件', () => {
it('onMouseMove', () => {
const onMouseMove = () => {
LogUtils.log('mousemove bubble');
};
const onMouseMoveCapture = () => {
LogUtils.log('mousemove capture');
};
test('mousemove', <div
onMouseMove={onMouseMove}
onMouseMoveCapture={onMouseMoveCapture}
/>)
});
it('onMouseDown', () => {
const onMousedown = () => {
LogUtils.log('mousedown bubble');
};
const onMousedownCapture = () => {
LogUtils.log('mousedown capture');
};
test('mousedown', <div
onMousedown={onMousedown}
onMousedownCapture={onMousedownCapture}
/>)
});
it('onMouseUp', () => {
const onMouseUp = () => {
LogUtils.log('mouseup bubble');
};
const onMouseUpCapture = () => {
LogUtils.log('mouseup capture');
};
test('mouseup', <div
onMouseUp={onMouseUp}
onMouseUpCapture={onMouseUpCapture}
/>)
});
it('onMouseOut', () => {
const onMouseOut = () => {
LogUtils.log('mouseout bubble');
};
const onMouseOutCapture = () => {
LogUtils.log('mouseout capture');
};
test('mouseout', <div
onMouseOut={onMouseOut}
onMouseOutCapture={onMouseOutCapture}
/>)
});
it('onMouseOver', () => {
const onMouseOver = () => {
LogUtils.log('mouseover bubble');
};
const onMouseOverCapture = () => {
LogUtils.log('mouseover capture');
};
test('mouseover', <div
onMouseOver={onMouseOver}
onMouseOverCapture={onMouseOverCapture}
/>)
});
})
})

View File

@ -0,0 +1,52 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
import * as LogUtils from '../jest/logUtils';
describe('合成滚轮事件', () => {
it('onWheel', () => {
const realNode = Horizon.render(
<div
onWheel={event => LogUtils.log(`onWheel: ${event.type}`)}
onWheelCapture={event => LogUtils.log(`onWheelCapture: ${event.type}`)}
/>, container);
realNode.dispatchEvent(
new MouseEvent('wheel', {
bubbles: true,
cancelable: false,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'onWheelCapture: wheel',
'onWheel: wheel'
]);
});
it('可以执行preventDefault和 stopPropagation', () => {
const eventHandler = e => {
expect(e.isDefaultPrevented()).toBe(false);
e.preventDefault();
expect(e.isDefaultPrevented()).toBe(true);
expect(e.isPropagationStopped()).toBe(false);
e.stopPropagation();
expect(e.isPropagationStopped()).toBe(true);
LogUtils.log(e.type + ' handle');
};
const realNode = Horizon.render(
<div onWheel={eventHandler}/>,
container
);
realNode.dispatchEvent(
new MouseEvent('wheel', {
bubbles: true,
cancelable: true,
}),
);
expect(LogUtils.getAndClear()).toEqual([
'wheel handle'
]);
});
})

View File

@ -0,0 +1,26 @@
import { allDelegatedNativeEvents } from '../../../libs/horizon/src/event/EventCollection';
import * as LogUtils from './logUtils';
export const stopBubbleOrCapture = (e, value) => {
LogUtils.log(value)
e.stopPropagation();
};
export const getEventListeners = (dom) => {
let ret = true
let keyArray = [];
for (var key in dom) {
keyArray.push(key);
}
try {
allDelegatedNativeEvents.forEach(event => {
if (!keyArray.includes(event)) {
ret = false;
throw new Error('没有挂载全量事件');
}
})
} catch (error) {
}
return ret;
};