Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add unit test for notice-bar #821

Merged
merged 2 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/notice-bar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ spline: message
isComponent: true
---

<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-94%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-94%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-88%25-blue" /></span>
## 引入

全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
Expand Down Expand Up @@ -51,6 +52,7 @@ isComponent: true

| 名称 | 类型 | 默认值 | 说明 | 必传 |
| ---- | ---- | ------ | ---- | -- |
external-classes | Array | - | 组件类名,分别用于设置 组件外层元素、文本内容、前缀图标、右侧额外信息、后缀图标 等元素类名。`['t-class', 't-class-content', 't-class-prefix-icon', 't-class-extra', 't-class-suffix-icon']` | N
| content | String / Slot | - | 文本内容 | N |
| extra | String / Slot | - | 右侧额外信息| N |
| marquee | Boolean / Object | false | 跑马灯效果。speed 指速度控制;loop 指循环播放次数,值为 -1 表示循环播放,值为 0 表示不循环播放;delay 表示延迟多久开始播放。TS 类型:`boolean | DrawMarquee` `interface DrawMarquee { speed?: number; loop?: number; delay?: number }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/notice-bar/type.ts) | N |
Expand Down
47 changes: 47 additions & 0 deletions src/notice-bar/__test__/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`notice-bar props : marquee 1`] = `
<main>
<t-notice-bar
class="base"
>
<wx-view
class="t-notice-bar t-notice-bar--info t-class"
>
<wx-view
class="t-notice-bar__prefix-icon t-class-prefix-icon"
bind:tap="clickPrefixIcon"
>
<t-icon>
<wx-label
class="t-class t-icon t-icon-error-circle-filled t-icon-base"
style=";;"
bind:tap="onTap"
/>
</t-icon>
</wx-view>
<wx-view
class="t-notice-bar__content-wrap"
bind:tap="clickContent"
>
<wx-view
animation=""
class="t-notice-bar__content t-class-content "
>
<wx-view>
提示文字描述提示文字描述提示文字描述提示文字描述文
</wx-view>
</wx-view>
</wx-view>
<wx-view
class="t-notice-bar__extra t-class-extra"
bind:tap="clickExtra"
/>
<wx-view
class="t-notice-bar__suffix-icon t-class-suffix-icon"
bind:tap="clickSuffixIcon"
/>
</wx-view>
</t-notice-bar>
</main>
`;
297 changes: 297 additions & 0 deletions src/notice-bar/__test__/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
import simulate from 'miniprogram-simulate';
import path from 'path';
import similateApi from 'miniprogram-simulate/src/api';
import * as Util from '../../common/utils';

// simulate提供一些基本的api,如getSystemInfoSync, createAnimation, 如果涉及到复杂的链式调用需要自行 mock
global.wx = {
...similateApi,
};

const mockGetAnimationFrame = jest.spyOn(Util, 'getAnimationFrame');
const mockGetRect = jest.spyOn(Util, 'getRect');

// 设置每次调用函数的值
mockGetAnimationFrame.mockImplementation((cb) => {
return cb();
});

// 调用函数第1次的返回值 nodeRect
mockGetRect.mockImplementationOnce(() => {
return {
width: 350,
};
});
// 调用函数第2次的返回值 warpID
mockGetRect.mockImplementationOnce(() => {
return {
width: 313,
};
});

describe('notice-bar', () => {
const noticeBar = simulate.load(path.resolve(__dirname, `../notice-bar`), 't-notice-bar', {
less: true,
rootPath: path.resolve(__dirname, '../..'),
});
jest.resetModules();
const icon = simulate.load(path.resolve(__dirname, `../../icon/icon`), 't-icon', {
less: true,
rootPath: path.resolve(__dirname, '../..'),
});

describe('props', () => {
it(': visible', () => {
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"></t-notice-bar>`,
data: {
visible: true,
},
usingComponents: {
't-notice-bar': noticeBar,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
expect(comp.querySelector('.base >>> .t-notice-bar')).toBeDefined();

comp.setData({
visible: false,
});
expect(comp.querySelector('.base >>> .t-notice-bar')).not.toBeDefined();

comp.detach();
});

it(': theme', () => {
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"
theme="{{theme}}"
></t-notice-bar>`,
data: {
visible: true,
theme: 'info',
},
usingComponents: {
't-notice-bar': noticeBar,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
const $component = comp.querySelector('.base >>> .t-notice-bar');
expect($component.dom.getAttribute('class').includes('t-notice-bar--info')).toBeTruthy();

comp.setData({
theme: 'success',
});
expect($component.dom.getAttribute('class').includes('t-notice-bar--success')).toBeTruthy();
});

it(': content', () => {
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"
content="{{content}}"></t-notice-bar>`,
data: {
visible: true,
content: 'notice-bar content',
},
usingComponents: {
't-notice-bar': noticeBar,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
const $noticeBar = comp.querySelector('.base');
const $content = comp.querySelector('.base >>> .t-notice-bar__content');

expect($content.dom.textContent.trim()).toBe($noticeBar.instance.data.content);
});

it(': extra', () => {
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"
extra="{{extra}}"></t-notice-bar>`,
data: {
visible: true,
extra: 'notice-bar extra',
},
usingComponents: {
't-notice-bar': noticeBar,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
const $noticeBar = comp.querySelector('.base');
const $extra = comp.querySelector('.base >>> .t-notice-bar__extra');

expect($extra.dom.textContent.trim()).toBe($noticeBar.instance.data.extra);
});

it(': prefix-icon', () => {
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"
prefixIcon="{{prefixIcon}}"></t-notice-bar>`,
data: {
visible: true,
prefixIcon: 'null',
},
usingComponents: {
't-notice-bar': noticeBar,
},
});

const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
const $prefixIcon = comp.querySelector('.base >>> .t-notice-bar__prefix-icon');
expect($prefixIcon.dom.innerHTML).toBe('');

comp.setData({
prefixIcon: 'add',
});

const iconId = simulate.load({
template: `<t-icon name="{{name}}"></t-icon>`,
data: {
name: 'add',
},
usingComponents: {
't-icon': icon,
},
});
const iconComp = simulate.render(iconId);
expect($prefixIcon.dom.innerHTML).toContain(iconComp.dom.innerHTML);
});

const delay = 7100;
it(
': marquee',
async () => {
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"
marquee="{{marquee}}"
content="{{content}}"
></t-notice-bar>`,
data: {
visible: true,
content: '提示文字描述提示文字描述提示文字描述提示文字描述文',
// marquee: true,
marquee: {
speed: 80,
loop: -1,
delay: 0,
},
},
usingComponents: {
't-notice-bar': noticeBar,
},
});

const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
await simulate.sleep(delay); // 等待 delay 后再继续后续代码的执行

expect(comp.toJSON()).toMatchSnapshot();
const $instance = comp.querySelector('.base');
const $content = comp.querySelector('.base >>> .t-notice-bar__content');
expect($content.dom.textContent.trim()).toBe($instance.data.content);

// TODO: marquee 需要支持 Object && Boolean, 单测环境中,marquee值会固定为默认值 false
// marquee = false, content内容开启超出换行
expect($content.dom.getAttribute('class')).not.toContain('t-notice-bar__content-wrapable');
// const componentInstance = simulate.render(noticeBar).instance;
// expect(componentInstance.data.marquee).toEqual(comp.instance.data.marquee);
},
delay,
);
});

describe('slots', () => {
it(': content', () => {
const text = 'content 内容';
const id = simulate.load({
template: `<t-notice-bar
class="base"
visible="{{visible}}"
>
<text slot="content">{{text}}</text>
</t-notice-bar>`,
data: {
visible: true,
text,
},
usingComponents: {
't-notice-bar': noticeBar,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
const $content = comp.querySelector('.base >>> .t-notice-bar__content');
expect($content.dom.textContent).toBe(text);
});
});

describe('event', () => {
let triggerName = null;
const click = jest.fn((e) => {
const { trigger } = e.detail;
triggerName = trigger;
});

it(': click', async () => {
const id = simulate.load({
template: `<t-notice-bar
class="base
visible="{{visible}}"
suffixIcon="chevron-right"
extra="详情"
content="提示文字描述提示文字描述提示文字描述"
bind:click="click"
></t-notice-bar>`,
data: {
visible: true,
},
methods: {
click,
},
usingComponents: {
't-notice-bar': noticeBar,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));
const $prefixIcon = comp.querySelector('.base >>> .t-notice-bar__prefix-icon');
const $content = comp.querySelector('.base >>> .t-notice-bar__content');
const $extra = comp.querySelector('.base >>> .t-notice-bar__extra');
const $suffixIcon = comp.querySelector('.base >>> .t-notice-bar__suffix-icon');
$prefixIcon.dispatchEvent('tap');
await simulate.sleep(0);
expect(triggerName).toBe('prefix-icon');
expect(click).toHaveBeenCalledTimes(1);
$content.dispatchEvent('tap');
await simulate.sleep(0);
expect(triggerName).toBe('content');
expect(click).toHaveBeenCalledTimes(2);
$extra.dispatchEvent('tap');
await simulate.sleep(0);
expect(triggerName).toBe('extra');
expect(click).toHaveBeenCalledTimes(3);

$suffixIcon.dispatchEvent('tap');
await simulate.sleep(0);
expect(triggerName).toBe('suffix-icon');
expect(click).toHaveBeenCalledTimes(4);
});
});
});
Loading