@wevu/test-utils 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,6 +51,16 @@ export default defineConfig({
51
51
  })
52
52
  ```
53
53
 
54
+ 默认情况下,`wevuSfc()` 会拒绝 `app.vue` 和 `pages/**` 下的页面文件,但允许 `pages/**/components/**` 中的普通组件。项目使用自定义页面目录时,可传入同步或异步的 `isPage(filename)` 判定;回调收到的是移除查询参数并统一为 `/` 分隔符的文件名:
55
+
56
+ ```ts
57
+ export default defineConfig({
58
+ plugins: [wevuSfc({
59
+ isPage: filename => filename.includes('/routes/'),
60
+ })],
61
+ })
62
+ ```
63
+
54
64
  ```ts
55
65
  import { mountComponent } from '@wevu/test-utils'
56
66
  import Counter from './Counter.vue'
@@ -69,7 +79,7 @@ expect(wrapper.vm.count.value).toBe(2)
69
79
  wrapper.unmount()
70
80
  ```
71
81
 
72
- `mountComponent()` 接收编译后的 SFC 默认导出、组件选项或 Wevu component definition,不接收源码路径或字符串。它复用组件自身的 props 默认值、data、computed、methods、watch、setup、Options API provide/inject、emits 和生命周期,挂载顺序为 `created -> attached -> ready`,卸载时调用 `detached`。
82
+ `mountComponent()` 接收编译后的 SFC 默认导出、组件选项或 Wevu component definition,不接收源码路径或字符串。它复用组件自身的 props 默认值、data、computed、methods、watch、setup、Options API provide/inject、emits 和生命周期,挂载顺序为 `created -> attached -> ready`,卸载时调用 `detached`。每次挂载都会创建独立的 Wevu app context,因此 `global.provide`、插件、mocks、全局属性和卸载状态不会在 wrapper 之间共享。
73
83
 
74
84
  `app.vue` 和页面组件不属于该入口的测试对象;需要验证完整编译产物、WXML 查询、组件树、宿主 mock 或交互时,请使用 `@mpcore/test`。
75
85
 
@@ -1 +1 @@
1
- import{applyDataPayload as e,applyGlobalOptions as t,createEmitted as n}from"./mountHelpers.mjs";import{nextTick as r}from"wevu";import{callHookList as i,createWevuComponentDefinition as a,getWevuComponentLifecycleDefinition as o}from"wevu/internal-runtime";function s(e){return!!(e&&(typeof e==`object`||typeof e==`function`)&&e.__wevu_runtime&&e.__wevu_options)}function c(e){if(s(e))return!0;if(!e||typeof e!=`object`)return!1;let t=e;return t.__wevu_isPage===!0||t.__wevu_isPage===!1||[`props`,`properties`,`data`,`computed`,`methods`,`watch`,`lifetimes`,`pageLifetimes`,`observers`,`beforeCreate`,`created`,`mounted`,`unmounted`].some(e=>e in t)}function l(e){if(s(e))return e;if(!e||typeof e!=`object`)throw TypeError(`mountComponent() 需要接收编译后的 Vue SFC、组件选项或 Wevu 组件定义`);return a(e)}function u(e,t=new WeakMap){if(!e||typeof e!=`object`)return e;if(t.has(e))return t.get(e);if(Array.isArray(e)){let n=[];return t.set(e,n),e.forEach(e=>n.push(u(e,t))),n}let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return e;let r={};t.set(e,r);for(let[n,i]of Object.entries(e))r[n]=u(i,t);return r}function d(e,t){var n;let r={};for(let[t,i]of Object.entries((n=e.properties)==null?{}:n))i&&typeof i==`object`&&`value`in i&&(r[t]=u(i.value));return Object.assign(r,t),r}function f(a,s={}){var c,u,f,p,m;let h=l(a),g=o(h);if(!g)throw TypeError(`mountComponent() 无法解析 Wevu 组件生命周期定义`);if(g.__wevu_isPage===!0)throw Error(`mountComponent() 不支持 app.vue 或页面组件,请改用 @mpcore/test`);let _=h.__wevu_options,v=h.__wevu_runtime,y=d(g,(c=s.props)==null?{}:c),b=Object.create(null),x=[],S=!1,C=typeof _.data==`function`?_.data():{},w={data:{...C==null?{}:C},properties:y,route:s.route,is:s.componentName,setData(t,n){var r,i;x.push({...t}),e(w.data,t);let a=(r=s.adapter)==null||(i=r.setData)==null?void 0:i.call(r,t);return a&&typeof a.then==`function`?a.then(()=>n==null?void 0:n()):(n==null||n(),a)},triggerEvent(e,t,n){var r;((r=b[e])==null?b[e]=[]:r).push([t])}};t(v,s);let T=(u=g.lifetimes)==null?{}:u;return(f=T.created)==null||f.call(w),(p=T.attached)==null||p.call(w),(m=T.ready)==null||m.call(w),{get vm(){var e;return(e=w.__wevu)==null?void 0:e.proxy},get instance(){return w.__wevu},host:w,setDataCalls:x,get isUnmounted(){return S},async setProps(e){var t,n,i;if(S)throw Error(`不能在已卸载的 wrapper 上调用 setProps()`);let a={...(t=w.properties)==null?{}:t};Object.assign((n=w.properties)==null?{}:n,e);let o=(i=g.observers)==null?{}:i;for(let[t,n]of Object.entries(e)){if(Object.is(a[t],n))continue;let e=o[t];typeof e==`function`&&e.call(w,n,a[t])}typeof o[`**`]==`function`&&o[`**`].call(w,w.properties,a),await r()},async setData(e){var t,n;if(S)throw Error(`不能在已卸载的 wrapper 上调用 setData()`);Object.assign(w.data,e),Object.assign((t=(n=w.__wevu)==null?void 0:n.state)==null?{}:t,e),await r()},emitted:n(b),async triggerHook(e,...t){if(S)throw Error(`不能在已卸载的 wrapper 上调用 triggerHook()`);i(w,e,t),await r()},nextTick:()=>r(),unmount(){var e;S||(S=!0,(e=T.detached)==null||e.call(w),v.unmount())}}}export{c as isComponentSubject,f as mountComponent};
1
+ import{applyDataPayload as e,applyGlobalOptions as t,createEmitted as n}from"./mountHelpers.mjs";import{nextTick as r}from"wevu";import{callHookList as i,createIsolatedWevuComponentDefinition as a,createWevuComponentDefinition as o,getWevuComponentLifecycleDefinition as s}from"wevu/internal-runtime";function c(e){return!!(e&&(typeof e==`object`||typeof e==`function`)&&e.__wevu_runtime&&e.__wevu_options)}function l(e){if(c(e))return!0;if(!e||typeof e!=`object`)return!1;let t=e;return t.__wevu_isPage===!0||t.__wevu_isPage===!1||[`props`,`properties`,`data`,`computed`,`methods`,`watch`,`lifetimes`,`pageLifetimes`,`observers`,`beforeCreate`,`created`,`mounted`,`unmounted`].some(e=>e in t)}function u(e){if(c(e))return a(e);if(!e||typeof e!=`object`)throw TypeError(`mountComponent() 需要接收编译后的 Vue SFC、组件选项或 Wevu 组件定义`);return o(e)}function d(e,t=new WeakMap){if(!e||typeof e!=`object`)return e;if(t.has(e))return t.get(e);if(Array.isArray(e)){let n=[];return t.set(e,n),e.forEach(e=>n.push(d(e,t))),n}let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return e;let r={};t.set(e,r);for(let[n,i]of Object.entries(e))r[n]=d(i,t);return r}function f(e,t){var n;let r={};for(let[t,i]of Object.entries((n=e.properties)==null?{}:n))i&&typeof i==`object`&&`value`in i&&(r[t]=d(i.value));return Object.assign(r,t),r}function p(a,o={}){var c,l,d,p,m;let h=u(a),g=s(h);if(!g)throw TypeError(`mountComponent() 无法解析 Wevu 组件生命周期定义`);if(g.__wevu_isPage===!0)throw Error(`mountComponent() 不支持 app.vue 或页面组件,请改用 @mpcore/test`);let _=h.__wevu_options,v=h.__wevu_runtime,y=f(g,(c=o.props)==null?{}:c),b=Object.create(null),x=[],S=!1,C=typeof _.data==`function`?_.data():{},w={data:{...C==null?{}:C},properties:y,route:o.route,is:o.componentName,setData(t,n){var r,i;x.push({...t}),e(w.data,t);let a=(r=o.adapter)==null||(i=r.setData)==null?void 0:i.call(r,t);return a&&typeof a.then==`function`?a.then(()=>n==null?void 0:n()):(n==null||n(),a)},triggerEvent(e,t,n){var r;((r=b[e])==null?b[e]=[]:r).push([t])}};t(v,o);let T=(l=g.lifetimes)==null?{}:l;return(d=T.created)==null||d.call(w),(p=T.attached)==null||p.call(w),(m=T.ready)==null||m.call(w),{get vm(){var e;return(e=w.__wevu)==null?void 0:e.proxy},get instance(){return w.__wevu},host:w,setDataCalls:x,get isUnmounted(){return S},async setProps(e){var t,n,i;if(S)throw Error(`不能在已卸载的 wrapper 上调用 setProps()`);let a={...(t=w.properties)==null?{}:t};Object.assign((n=w.properties)==null?{}:n,e);let o=(i=g.observers)==null?{}:i;for(let[t,n]of Object.entries(e)){if(Object.is(a[t],n))continue;let e=o[t];typeof e==`function`&&e.call(w,n,a[t])}typeof o[`**`]==`function`&&o[`**`].call(w,w.properties,a),await r()},async setData(e){var t,n;if(S)throw Error(`不能在已卸载的 wrapper 上调用 setData()`);Object.assign(w.data,e),Object.assign((t=(n=w.__wevu)==null?void 0:n.state)==null?{}:t,e),await r()},emitted:n(b),async triggerHook(e,...t){if(S)throw Error(`不能在已卸载的 wrapper 上调用 triggerHook()`);i(w,e,t),await r()},nextTick:()=>r(),unmount(){if(!S){S=!0;try{var e;(e=T.detached)==null||e.call(w)}finally{v.unmount()}}}}}export{l as isComponentSubject,p as mountComponent};
package/dist/vitest.d.mts CHANGED
@@ -17,11 +17,14 @@ interface WevuSfcPlugin {
17
17
  map: any;
18
18
  }>;
19
19
  }
20
+ interface WevuSfcOptions {
21
+ isPage?: (filename: string) => boolean | Promise<boolean>;
22
+ }
20
23
  /**
21
24
  * 为 Vitest 提供 Wevu SFC 逻辑编译入口。
22
25
  *
23
26
  * 该插件只输出 SFC script,不加载 Vue Web runtime,也不渲染模板、样式或 WXML。
24
27
  */
25
- declare function wevuSfc(): WevuSfcPlugin;
28
+ declare function wevuSfc(options?: WevuSfcOptions): WevuSfcPlugin;
26
29
  //#endregion
27
- export { WevuSfcPlugin, wevuSfc };
30
+ export { WevuSfcOptions, WevuSfcPlugin, wevuSfc };
package/dist/vitest.mjs CHANGED
@@ -1 +1 @@
1
- import{WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID as e,WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID as t,WEAPP_VITE_RUNTIME_VIRTUAL_ID as n}from"@weapp-core/constants";import{compileVueFile as r}from"@wevu/compiler";const i={[n]:`wevu/internal-runtime`,[e]:`wevu/internal-reactivity`,[t]:`wevu/internal-template`};function a(e){return/\.vue(?:$|\?)/.test(e)}function o(e){let t=e.split(`?`)[0].replaceAll(`\\`,`/`);return/(?:^|\/)app\.vue$/.test(t)||/(?:^|\/)pages?(?:\/|$)/.test(t)}function s(){return{name:`wevu-test-utils:sfc`,enforce:`pre`,async resolveId(e,t){var n;let r=i[e];if(!r)return;let a=await this.resolve(r,t,{skipSelf:!0});return(n=a==null?void 0:a.id)==null?r:n},async transform(e,t){var n,i;if(!a(t))return;if(o(t))throw Error(`@wevu/test-utils/vitest 不支持 app.vue 或页面组件:${t},请改用 @mpcore/test`);let s=await r(e,t.split(`?`)[0],{skipComponentTransform:!0,sourceMap:!0});return{code:(n=s.script)==null?`export default {}`:n,map:(i=s.scriptMap)==null?null:i}}}}export{s as wevuSfc};
1
+ import{WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID as e,WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID as t,WEAPP_VITE_RUNTIME_VIRTUAL_ID as n}from"@weapp-core/constants";import{compileVueFile as r}from"@wevu/compiler";const i={[n]:`wevu/internal-runtime`,[e]:`wevu/internal-reactivity`,[t]:`wevu/internal-template`};function a(e){return/\.vue(?:$|\?)/.test(e)}function o(e){return e.split(`?`)[0].replaceAll(`\\`,`/`)}function s(e){return/(?:^|\/)app\.vue$/.test(e)}function c(e){return/(?:^|\/)pages?(?:\/|$)/.test(e)&&!/(?:^|\/)components?(?:\/|$)/.test(e)}function l(e={}){return{name:`wevu-test-utils:sfc`,enforce:`pre`,async resolveId(e,t){var n;let r=i[e];if(!r)return;let a=await this.resolve(r,t,{skipSelf:!0});return(n=a==null?void 0:a.id)==null?r:n},async transform(t,n){var i,l;if(!a(n))return;let u=o(n),d=e.isPage?await e.isPage(u):c(u);if(s(u)||d)throw Error(`@wevu/test-utils/vitest 不支持 app.vue 或页面组件:${n},请改用 @mpcore/test`);let f=await r(t,u,{skipComponentTransform:!0,sourceMap:!0});return{code:(i=f.script)==null?`export default {}`:i,map:(l=f.scriptMap)==null?null:l}}}}export{l as wevuSfc};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/test-utils",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "description": "Lightweight test utilities for Wevu Composition API logic",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -41,14 +41,14 @@
41
41
  "node": "^20.19.0 || >=22.12.0"
42
42
  },
43
43
  "peerDependencies": {
44
- "wevu": "6.20.5"
44
+ "wevu": "6.22.0"
45
45
  },
46
46
  "dependencies": {
47
- "@weapp-core/constants": "0.1.17",
48
- "@wevu/compiler": "6.20.5"
47
+ "@weapp-core/constants": "0.2.0",
48
+ "@wevu/compiler": "6.22.0"
49
49
  },
50
50
  "devDependencies": {
51
- "wevu": "6.20.5"
51
+ "wevu": "6.22.0"
52
52
  },
53
53
  "publishConfig": {
54
54
  "access": "public",