Browse Source

feat(tabbar): add test (#1013)

* fix: 新增tabbar单元测试
Drjingfubo 3 years ago
parent
commit
bf1114b71c

+ 2 - 2
jest.config.js

@@ -1,5 +1,5 @@
 module.exports = {
-  moduleFileExtensions: ['vue', 'js', 'ts'],
+  moduleFileExtensions: ['vue', 'js', 'ts', 'tsx'],
   preset: 'ts-jest',
   testEnvironment: 'jsdom',
   transform: {
@@ -7,7 +7,7 @@ module.exports = {
     '^.+\\.ts$': 'ts-jest' // ts 文件用 ts-jest 转换
   },
   // 匹配 __tests__ 目录下的 .js/.ts 文件 或其他目录下的 xx.test.js/ts xx.spec.js/ts
-  testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(ts)$',
+  testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(ts|tsx)$',
   //testRegex: '__tests__.action.spec.ts',
   // 支持源代码中相同的 `@` -> `src` 别名
   moduleNameMapper: {

+ 21 - 2
src/packages/__VUE/actionsheet/__test__/index.spec.ts

@@ -1,4 +1,23 @@
-import { mount } from '@vue/test-utils';
+import { config, mount } from '@vue/test-utils';
 import ActionSheet from '../index.vue';
+import NutIcon from '../../icon/index.vue';
+import NutPopup from '../../icon/index.vue';
 
-test('');
+beforeAll(() => {
+  config.global.components = {
+    NutIcon,
+    NutPopup
+  };
+});
+
+afterAll(() => {
+  config.global.components = {};
+});
+
+test('should render shortpassword when visible is true', async () => {
+  const wrapper = mount(ActionSheet, {
+    props: {
+      visible: true
+    }
+  });
+});

+ 10 - 26
src/packages/__VUE/actionsheet/index.vue

@@ -1,17 +1,9 @@
 <template>
   <view :class="classes">
-    <nut-popup
-      pop-class="popclass"
-      :visible="visible"
-      position="bottom"
-      round
-      @click-overlay="close"
-    >
+    <nut-popup pop-class="popclass" :visible="visible" position="bottom" round @click-overlay="close">
       <view class="nut-actionsheet-panel">
         <view v-if="title" class="nut-actionsheet-title">{{ title }}</view>
-        <view class="nut-actionsheet-item desc" v-if="description">{{
-          description
-        }}</view>
+        <view class="nut-actionsheet-item desc" v-if="description">{{ description }}</view>
         <view class="nut-actionsheet-menu" v-if="menuItems.length">
           <view
             v-for="(item, index) of menuItems"
@@ -20,26 +12,21 @@
             :style="{ color: isHighlight(item) }"
             :key="index"
             @click="chooseItem(item, index)"
-            >{{ item[optionTag]
-            }}<view class="subdesc">{{ item[optionSubTag] }}</view>
+            >{{ item[optionTag] }}<view class="subdesc">{{ item[optionSubTag] }}</view>
           </view>
         </view>
-        <view
-          class="nut-actionsheet-cancel"
-          v-if="cancelTxt"
-          @click="cancelActionSheet"
-        >
+        <view class="nut-actionsheet-cancel" v-if="cancelTxt" @click="cancelActionSheet">
           {{ cancelTxt }}
         </view>
       </view>
     </nut-popup>
   </view>
 </template>
-<script>
+<script lang="ts">
 import { createComponent } from '../../utils/create';
 import { computed } from 'vue';
-const { componentName, create } = createComponent('actionsheet');
 import { popupProps } from '../popup/index.vue';
+const { componentName, create } = createComponent('actionsheet');
 export default create({
   props: {
     ...popupProps,
@@ -76,7 +63,7 @@ export default create({
       default: () => []
     }
   },
-  emits: ['cancel', 'choose', 'update:visible'],
+  emits: ['cancel', 'close', 'choose', 'update:visible'],
 
   setup(props, { emit }) {
     const classes = computed(() => {
@@ -86,11 +73,8 @@ export default create({
       };
     });
 
-    const isHighlight = (item) => {
-      return props.chooseTagValue &&
-        props.chooseTagValue === item[props.optionTag]
-        ? props.color
-        : '#1a1a1a';
+    const isHighlight = (item: { [x: string]: string }) => {
+      return props.chooseTagValue && props.chooseTagValue === item[props.optionTag] ? props.color : '#1a1a1a';
     };
 
     const cancelActionSheet = () => {
@@ -98,7 +82,7 @@ export default create({
       emit('update:visible', false);
     };
 
-    const chooseItem = (item, index) => {
+    const chooseItem = (item: { disable: any }, index: any) => {
       if (!item.disable) {
         emit('choose', item, index);
         emit('update:visible', false);

+ 1 - 1
src/packages/__VUE/shortpassword/__tests__/index.spec.ts

@@ -56,7 +56,7 @@ test('should render buttonShortpassword and error msg when noButton is false ',
   expect((wrapper.emitted('ok') as any)[0][0]).toBe('123');
 });
 
-test('should allow to format value with formatter prop', async () => {
+test('should change  value when prop changed', async () => {
   const wrapper = mount(ShortPassword, {
     props: {
       visible: true,

+ 3 - 0
src/packages/__VUE/tabbar/__test__/__snapshots__/index.spec.ts.snap

@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render fixed element when using bottom prop 1`] = `"<view class=\\"nut-tabbar nut-tabbar-bottom nut-tabbar-safebottom\\"></view>"`;

+ 178 - 0
src/packages/__VUE/tabbar/__test__/index.spec.ts

@@ -0,0 +1,178 @@
+import { config, DOMWrapper, mount } from '@vue/test-utils';
+import Tabbar from '../index.vue';
+import TabbarItem from '../../tabbaritem/index.vue';
+import NutIcon from '../../icon/index.vue';
+import { nextTick } from 'vue';
+
+// 模拟setup导入资源
+jest.mock('vue-router', () => ({
+  useRouter: jest.fn()
+}));
+// 所有的测试用例之前执行一次
+beforeAll(() => {
+  config.global.components = {
+    NutIcon
+  };
+});
+// 所有的测试用例之后执行一次
+afterAll(() => {
+  config.global.components = {};
+});
+// 测试用例
+test('should render tabbar when default', async () => {
+  const wrapper = mount({
+    components: {
+      Tabbar: Tabbar,
+      TabbarItem: TabbarItem
+    },
+    template: `
+    <Tabbar>
+      <TabbarItem tab-title="首页" icon="home"></TabbarItem>
+      <TabbarItem tab-title="分类" icon="category"></TabbarItem>
+      <TabbarItem tab-title="发现" icon="find"></TabbarItem>
+    </Tabbar>
+    `,
+    setup() {}
+  });
+  await nextTick();
+  // 断言 期望值
+  expect(wrapper.find('.nut-tabbar').exists()).toBe(true);
+  expect(wrapper.find('.nut-tabbar-item').exists()).toBe(true);
+  expect(wrapper.find('.nut-tabbar-item_icon-box_icon').exists()).toBe(true);
+});
+
+test('should render custom img when using img prop', async () => {
+  const wrapper = mount({
+    components: {
+      Tabbar: Tabbar,
+      TabbarItem: TabbarItem
+    },
+    template: `
+    <Tabbar>
+      <TabbarItem
+        tab-title="首页"
+        img="http://img13.360buyimg.com/uba/jfs/t1/29316/38/1115/3203/5c0f3d61E35d0c7da/9e557f2cb5c9dab6.jpg"
+        activeImg="http://img20.360buyimg.com/uba/jfs/t1/9996/36/8646/4833/5c0f3d61E7c1b7e0f/c98ad61124172e93.jpg"
+      ></TabbarItem>
+      <TabbarItem
+        tab-title="分类"
+        img="http://img12.360buyimg.com/uba/jfs/t1/25443/23/1062/4600/5c0f3d61E2e9f1360/c9b3421fe18614e2.jpg"
+        activeImg="http://img20.360buyimg.com/uba/jfs/t1/19241/12/1048/8309/5c0f3d61E17ed5a56/c3af0964cade47f8.jpg"
+      ></TabbarItem>
+    </Tabbar>
+    `
+  });
+  await nextTick();
+  const tabbarItemIcon: any = wrapper.findAll('.nut-tabbar-item_icon-box_icon');
+  expect(tabbarItemIcon[0].element.style.backgroundImage).toContain('c98ad61124172e93');
+  expect(tabbarItemIcon[1].element.style.backgroundImage).toContain('c9b3421fe18614e2');
+});
+
+test('should render custom check and icon size when using visible', async () => {
+  const wrapper = mount({
+    components: {
+      Tabbar: Tabbar,
+      TabbarItem: TabbarItem
+    },
+    template: `
+    <Tabbar visible="1" active-color="blue"  size="18px">
+      <TabbarItem tab-title="首页" icon="home"></TabbarItem>
+      <TabbarItem tab-title="分类" icon="category"></TabbarItem>
+    </Tabbar>
+    `
+  });
+  await nextTick();
+  const tabbarItem: any = wrapper.findAll('.nut-tabbar-item');
+  expect(tabbarItem[0].element.style.color).toEqual('rgb(0, 0, 0)');
+  expect(tabbarItem[1].element.style.color).toEqual('blue');
+  expect(wrapper.find<HTMLElement>('.nut-icon').element.style.fontSize).toEqual('18px');
+});
+
+test('should render custom color and bage when using prop', async () => {
+  const wrapper = mount({
+    components: {
+      Tabbar: Tabbar,
+      TabbarItem: TabbarItem
+    },
+    template: `
+    <Tabbar unactive-color="grey" active-color="blue">
+      <TabbarItem tab-title="首页" icon="home" num="11"></TabbarItem>
+      <TabbarItem tab-title="分类" icon="category"></TabbarItem>
+      <TabbarItem tab-title="发现" icon="find"></TabbarItem>
+
+    </Tabbar>
+    `
+  });
+  await nextTick();
+  const tabbarItem: any = wrapper.findAll('.nut-tabbar-item');
+  expect(tabbarItem.length).toBe(3);
+  expect(tabbarItem[0].element.style.color).toEqual('blue');
+  expect(tabbarItem[1].element.style.color).toEqual('grey');
+  expect(wrapper.find<HTMLElement>('.nut-tabbar-item_icon-box_tips').exists()).toBe(true);
+});
+
+test('should render fixed element when using bottom prop', async () => {
+  const wrapper = mount(Tabbar, {
+    props: {
+      bottom: true,
+      safeAreaInsetBottom: true
+    }
+  });
+  expect(wrapper.html()).toMatchSnapshot();
+});
+test('should match active tabbar by clcik', async () => {
+  const wrapper = mount({
+    components: {
+      Tabbar: Tabbar,
+      TabbarItem: TabbarItem
+    },
+    template: `
+    <Tabbar unactive-color="grey" active-color="blue">
+      <TabbarItem tab-title="首页" icon="home" num="11"></TabbarItem>
+      <TabbarItem tab-title="分类" icon="category"></TabbarItem>
+      <TabbarItem tab-title="发现" icon="find"></TabbarItem>
+    </Tabbar>
+    `
+  });
+  const tabbarItem: any = wrapper.findAll('.nut-tabbar-item');
+
+  expect(tabbarItem[0].element.style.color).toEqual('blue');
+
+  await tabbarItem[1].trigger('click');
+  expect(tabbarItem[1].element.style.color).toEqual('blue');
+  await tabbarItem[2].trigger('click');
+  expect(tabbarItem[2].element.style.color).toEqual('blue');
+});
+
+test('should show sure emitted when click', async () => {
+  const wrapper = mount({
+    components: {
+      Tabbar: Tabbar,
+      TabbarItem: TabbarItem
+    },
+    template: `
+    <Tabbar @tab-switch="tabSwitch">
+      <TabbarItem tab-title="首页" icon="home"  to='/home'></TabbarItem>
+      <TabbarItem tab-title="分类" icon="category"  to='/find'></TabbarItem>
+      <TabbarItem tab-title="发现" icon="find"></TabbarItem>
+    </Tabbar>
+    `,
+    data: () => {
+      return {
+        val: -1,
+        data: [] as any
+      };
+    },
+    methods: {
+      tabSwitch(item: any, index: number) {
+        this.val = index;
+        this.data = item;
+      }
+    }
+  });
+  const tabbarItem: any = wrapper.findAll('.nut-tabbar-item');
+  await tabbarItem[1].trigger('click');
+  await nextTick();
+  expect(wrapper.vm.val).toBe(1);
+  expect(wrapper.vm.data.tabTitle).toBe('分类');
+});