wrapito 13.2.2 → 13.3.0-beta10

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/dist/index.d.cts CHANGED
@@ -11,6 +11,7 @@ interface RequestOptions {
11
11
  host?: string;
12
12
  body?: object | string;
13
13
  method?: HttpMethod;
14
+ headers?: Record<string, string>;
14
15
  }
15
16
  interface WrapResponse extends Partial<Response> {
16
17
  /** The call's path we want to mock */
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ interface RequestOptions {
11
11
  host?: string;
12
12
  body?: object | string;
13
13
  method?: HttpMethod;
14
+ headers?: Record<string, string>;
14
15
  }
15
16
  interface WrapResponse extends Partial<Response> {
16
17
  /** The call's path we want to mock */
package/dist/index.js CHANGED
@@ -1,9 +1,12 @@
1
- "use strict";var me=Object.create;var O=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,ge=Object.prototype.hasOwnProperty;var ye=(e,t)=>{for(var n in t)O(e,n,{get:t[n],enumerable:!0})},j=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of he(t))!ge.call(e,o)&&o!==n&&O(e,o,{get:()=>t[o],enumerable:!(s=de(t,o))||s.enumerable});return e};var T=(e,t,n)=>(n=e!=null?me(fe(e)):{},j(t||!e||!e.__esModule?O(n,"default",{value:e,enumerable:!0}):n,e)),Re=e=>j(O({},"__esModule",{value:!0}),e);var ze={};ye(ze,{assertions:()=>Ye,configure:()=>be,getConfig:()=>d,matchers:()=>Ye,wrap:()=>ve});module.exports=Re(ze);var J=T(require("react"),1);var b=T(require("chalk"),1);var C=T(require("object-hash"),1);var N=require("@testing-library/react"),A={defaultHost:"",extend:{},mount:N.render,changeRoute:e=>window.history.replaceState(null,"",e)};function be(e){A={...A,...e}}var d=()=>({...A});var $=e=>t=>{let{method:n="GET",path:s,host:o=d().defaultHost,requestBody:r=void 0,catchParams:a}=t,l=o+s,i=!d().handleQueryParams||a,u=(0,C.default)({url:i?l:l.split("?")[0],method:n.toUpperCase(),requestBody:r}),p;return"_bodyInit"in e&&e._bodyInit!==void 0&&(p=JSON.parse(e._bodyInit)),(0,C.default)({url:i?e.url:e.url.split("?")[0],method:e.method,requestBody:p})===u};function E(e,t){if(!e)throw new Error(t)}function w(e,t){return typeof t===e}function Ie(e){return e instanceof Promise}function D(e,t,n){Object.defineProperty(e,t,n)}function x(e,t,n){Object.defineProperty(e,t,{value:n})}var M=Symbol.for("tinyspy:spy"),we=new Set,xe=e=>{e.called=!1,e.callCount=0,e.calls=[],e.results=[],e.next=[]},ke=e=>(D(e,M,{value:{reset:()=>xe(e[M])}}),e[M]),P=e=>e[M]||ke(e);function Me(e){E(w("function",e)||w("undefined",e),"cannot spy on a non-function value");let t=function(...s){let o=P(t);o.called=!0,o.callCount++,o.calls.push(s);let r=o.next.shift();if(r){o.results.push(r);let[u,p]=r;if(u==="ok")return p;throw p}let a,l="ok";if(o.impl)try{new.target?a=Reflect.construct(o.impl,s,new.target):a=o.impl.apply(this,s),l="ok"}catch(u){throw a=u,l="error",o.results.push([l,u]),u}let i=[l,a];if(Ie(a)){let u=a.then(p=>i[1]=p).catch(p=>{throw i[0]="error",i[1]=p,p});Object.assign(u,a),a=u}return o.results.push(i),a};x(t,"_isMockFunction",!0),x(t,"length",e?e.length:0),x(t,"name",e&&e.name||"spy");let n=P(t);return n.reset(),n.impl=e,t}var L=(e,t)=>Object.getOwnPropertyDescriptor(e,t),F=(e,t)=>{t!=null&&typeof t=="function"&&t.prototype!=null&&Object.setPrototypeOf(e.prototype,t.prototype)};function _(e,t,n){E(!w("undefined",e),"spyOn could not find an object to spy upon"),E(w("object",e)||w("function",e),"cannot spyOn on a primitive value");let[s,o]=(()=>{if(!w("object",t))return[t,"value"];if("getter"in t&&"setter"in t)throw new Error("cannot spy on both getter and setter");if("getter"in t)return[t.getter,"get"];if("setter"in t)return[t.setter,"set"];throw new Error("specify getter or setter to spy on")})(),r=L(e,s),a=Object.getPrototypeOf(e),l=a&&L(a,s),i=r||l;E(i||s in e,`${String(s)} does not exist`);let u=!1;o==="value"&&i&&!i.value&&i.get&&(o="get",u=!0,n=i.get());let p;i?p=i[o]:o!=="value"?p=()=>e[s]:p=e[s],n||(n=p);let m=Me(n);o==="value"&&F(m,p);let c=f=>{let{value:k,...v}=i||{configurable:!0,writable:!0};o!=="value"&&delete v.writable,v[o]=f,D(e,s,v)},g=()=>i?D(e,s,i):c(p),h=m[M];return x(h,"restore",g),x(h,"getOriginal",()=>u?p():p),x(h,"willCall",f=>(h.impl=f,m)),c(u?()=>(F(m,n),m):m),we.add(m),m}var Te=new Set,Ee=0;function Pe(e){let t=e,n,s=[],o=[],r=P(e),a={get calls(){return r.calls},get instances(){return s},get invocationCallOrder(){return o},get results(){return r.results.map(([c,g])=>({type:c==="error"?"throw":"return",value:g}))},get lastCall(){return r.calls[r.calls.length-1]}},l=[],i=!1;function u(...c){return s.push(this),o.push(++Ee),(i?n:l.shift()||n||r.getOriginal()||(()=>{})).apply(this,c)}let p=t.name;t.getMockName=()=>p||"vi.fn()",t.mockName=c=>(p=c,t),t.mockClear=()=>(r.reset(),s=[],o=[],t),t.mockReset=()=>(t.mockClear(),n=()=>{},l=[],t),t.mockRestore=()=>(t.mockReset(),r.restore(),n=void 0,t),t.getMockImplementation=()=>n,t.mockImplementation=c=>(n=c,r.willCall(u),t),t.mockImplementationOnce=c=>(l.push(c),t);function m(c,g){let h=n;n=c,r.willCall(u),i=!0;let f=()=>{n=h,i=!1},k=g();return k instanceof Promise?k.then(()=>(f(),t)):(f(),t)}return t.withImplementation=m,t.mockReturnThis=()=>t.mockImplementation(function(){return this}),t.mockReturnValue=c=>t.mockImplementation(()=>c),t.mockReturnValueOnce=c=>t.mockImplementationOnce(()=>c),t.mockResolvedValue=c=>t.mockImplementation(()=>Promise.resolve(c)),t.mockResolvedValueOnce=c=>t.mockImplementationOnce(()=>Promise.resolve(c)),t.mockRejectedValue=c=>t.mockImplementation(()=>Promise.reject(c)),t.mockRejectedValueOnce=c=>t.mockImplementationOnce(()=>Promise.reject(c)),Object.defineProperty(t,"mock",{get:()=>a}),r.willCall(u),Te.add(t),t}var U=e=>Pe(_({spy:e||(()=>{})},"spy"));beforeEach(()=>{global.window.fetch=U()});afterEach(()=>{global.window.fetch.mockReset()});var Ue=async()=>{let e={json:()=>Promise.resolve(),status:200,ok:!0,headers:new Headers({"Content-Type":"application/json"})};return Promise.resolve(e)},G=async e=>{let{responseBody:t,status:n=200,headers:s={},delay:o}=e,r={json:()=>Promise.resolve(t),status:n,ok:n>=200&&n<=299,headers:new Headers({"Content-Type":"application/json",...s})};return o?new Promise(a=>setTimeout(()=>a(r),o)):Promise.resolve(r)},qe=e=>console.warn(`
2
- ${b.default.white.bold.bgRed("wrapito")} ${b.default.redBright.bold("cannot find any mock matching:")}
3
- ${b.default.greenBright(`URL: ${e.url}`)}
4
- ${b.default.greenBright(`METHOD: ${e.method?.toLowerCase()}`)}
5
- ${b.default.greenBright(`REQUEST BODY: ${e._bodyInit}`)}
6
- `),V=async(e,t,n)=>{let s=e.find($(t));if(!s)return n&&qe(t),Ue();let{multipleResponses:o}=s;if(!o)return G(s);let r=o.find(a=>!a.hasBeenReturned);if(!r){n&&We(s);return}return r.hasBeenReturned=!0,G(r)},Q=(e=[],t=!1)=>{global.window.fetch.mockImplementation((s,o)=>{if(typeof s=="string"){let a=new Request(s,o);return V(e,a,t)}return V(e,s,t)})},We=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,n=b.default.greenBright(t);console.warn(n)};var S,y=e=>{S={...S,...e}},R=()=>({...S});beforeEach(()=>{global.fetch=U()});afterEach(()=>{global.fetch.mockReset()});var ve=e=>(y({Component:e,responses:[],props:{},path:"",hasPath:!1,interactionConfig:void 0,debug:process.env.npm_config_debugRequests==="true"}),I()),I=()=>{let e=Se();return{withProps:He,withNetwork:je,withInteraction:Be,atPath:Ne,debugRequests:$e,mount:Le,...e}},Ae=e=>{let t=R(),n=[...t.responses,...e];y({...t,responses:n})},Ce=(e,t)=>(t({addResponses:Ae},e),I()),De=(e,t)=>{let{extend:n}=d(),s=n[t];return{...e,[t]:(...o)=>Ce(o,s)}},Se=()=>{let{extend:e}=d();return Object.keys(e).reduce(De,{})},He=e=>{let t=R();return y({...t,props:e}),I()},Be=e=>{let t=R();return y({...t,interactionConfig:e}),I()},je=(e=[])=>{let t=R(),n=Array.isArray(e)?e:[e];return y({...t,responses:[...t.responses,...n]}),I()},Ne=(e,t)=>{let n=R();return y({...n,historyState:t,path:e,hasPath:!0}),I()},$e=()=>{let e=R();return y({...e,debug:!0}),I()},Le=()=>{let{portal:e,portals:t,changeRoute:n,history:s,mount:o,interaction:r}=d(),{Component:a,props:l,responses:i,path:u,hasPath:p,debug:m,historyState:c,interactionConfig:g}=R(),h=a;e&&Y(e),t&&Fe(t),p&&s&&(console.warn("wrapito WARNING: history is DEPRECATED. Pass a changeRoute function to the config instead."),console.warn("Read about changeRoute in: https://github.com/mercadona/wrapito#changeRoute"),s.push(u,c)),p&&!s&&n(u),Q(i,m);let f=o(J.createElement(h,{...l}));if(r){let k=r.setup?r.setup(r.userLib,g):r.userLib;return{...f,user:k}}return{...f,user:void 0}},Y=e=>{if(document.getElementById(e))return;let t=document.createElement("div");t.setAttribute("id",e),t.setAttribute("data-testid",e),document.body.appendChild(t)},Fe=e=>{e.forEach(t=>{Y(t)})};var z=require("jest-diff"),H=(e,t)=>{let n=t?.host?`\u{1F32F} Wrapito: ${t?.host}${e} ain't got called`:`\u{1F32F} Wrapito: ${e} ain't got called`;return{pass:!1,message:()=>n}},K=(e,t,n)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${n} times, you expected ${t} times`}),X=(e,t)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch method does not match, expected ${e} received ${t??"none"}`}),Z=(e,t)=>{let n=t.map(s=>(0,z.diff)(e,s)).join(`
1
+ "use strict";var re=Object.create;var y=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var ce=Object.getPrototypeOf,pe=Object.prototype.hasOwnProperty;var ue=(e,t)=>{for(var s in t)y(e,s,{get:t[s],enumerable:!0})},D=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ie(t))!pe.call(e,n)&&n!==s&&y(e,n,{get:()=>t[n],enumerable:!(o=ae(t,n))||o.enumerable});return e};var x=(e,t,s)=>(s=e!=null?re(ce(e)):{},D(t||!e||!e.__esModule?y(s,"default",{value:e,enumerable:!0}):s,e)),de=e=>D(y({},"__esModule",{value:!0}),e);var Be={};ue(Be,{assertions:()=>Ae,configure:()=>he,getConfig:()=>u,matchers:()=>Ae,wrap:()=>le});module.exports=de(Be);var C=x(require("react"),1);var g=x(require("chalk"),1);var q=x(require("object-hash"),1);var O=require("@testing-library/react"),I={defaultHost:"",extend:{},mount:O.render,changeRoute:e=>window.history.replaceState(null,"",e)};function he(e){I={...I,...e}}var u=()=>({...I});var H=e=>t=>{let{method:s="GET",path:o,host:n=u().defaultHost,requestBody:r=void 0,catchParams:a}=t,d=n+o,p=!u().handleQueryParams||a,c=(0,q.default)({url:p?d:d.split("?")[0],method:s.toUpperCase(),requestBody:r}),i;return"_bodyInit"in e&&e._bodyInit!==void 0&&(i=JSON.parse(e._bodyInit)),(0,q.default)({url:p?e.url:e.url.split("?")[0],method:e.method,requestBody:i})===c};var me=async()=>{let e={json:()=>Promise.resolve(),status:200,ok:!0,headers:new Headers({"Content-Type":"application/json"})};return Promise.resolve(e)},P=async e=>{let{responseBody:t,status:s=200,headers:o={},delay:n}=e,r={json:()=>Promise.resolve(t),status:s,ok:s>=200&&s<=299,headers:new Headers({"Content-Type":"application/json",...o})};return n?new Promise(a=>setTimeout(()=>a(r),n)):Promise.resolve(r)},ge=e=>console.warn(`
2
+ ${g.default.white.bold.bgRed("wrapito")} ${g.default.redBright.bold("cannot find any mock matching:")}
3
+ ${g.default.greenBright(`URL: ${e.url}`)}
4
+ ${g.default.greenBright(`METHOD: ${e.method?.toLowerCase()}`)}
5
+ ${g.default.greenBright(`REQUEST BODY: ${e._bodyInit}`)}
6
+ `),A=async(e,t,s)=>{let o=e.find(H(t));if(!o)return s&&ge(t),me();let{multipleResponses:n}=o;if(!n)return P(o);let r=n.find(a=>!a.hasBeenReturned);if(!r){s&&fe(o);return}return r.hasBeenReturned=!0,P(r)},B=(e=[],t=!1)=>{global.window.fetch.mockImplementation((o,n)=>{if(typeof o=="string"){let a=new Request(o,n);return A(e,a,t)}return A(e,o,t)})},fe=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,s=g.default.greenBright(t);console.warn(s)};var E,h=e=>{E={...E,...e}},m=()=>({...E});var N=require("@vitest/spy");beforeEach(()=>{global.fetch=(0,N.createMockInstance)()});afterEach(()=>{global.fetch.mockReset()});var le=e=>(h({Component:e,responses:[],props:{},path:"",hasPath:!1,interactionConfig:void 0,debug:process.env.npm_config_debugRequests==="true"}),f()),f=()=>{let e=be();return{withProps:Me,withNetwork:qe,withInteraction:Ie,atPath:Ee,debugRequests:we,mount:Ue,...e}},Re=e=>{let t=m(),s=[...t.responses,...e];h({...t,responses:s})},ye=(e,t)=>(t({addResponses:Re},e),f()),xe=(e,t)=>{let{extend:s}=u(),o=s[t];return{...e,[t]:(...n)=>ye(n,o)}},be=()=>{let{extend:e}=u();return Object.keys(e).reduce(xe,{})},Me=e=>{let t=m();return h({...t,props:e}),f()},Ie=e=>{let t=m();return h({...t,interactionConfig:e}),f()},qe=(e=[])=>{let t=m(),s=Array.isArray(e)?e:[e];return h({...t,responses:[...t.responses,...s]}),f()},Ee=(e,t)=>{let s=m();return h({...s,historyState:t,path:e,hasPath:!0}),f()},we=()=>{let e=m();return h({...e,debug:!0}),f()},Ue=()=>{let{portal:e,portals:t,changeRoute:s,history:o,mount:n,interaction:r}=u(),{Component:a,props:d,responses:p,path:c,hasPath:i,debug:R,historyState:M,interactionConfig:se}=m(),oe=a;e&&v(e),t&&We(t),i&&o&&(console.warn("wrapito WARNING: history is DEPRECATED. Pass a changeRoute function to the config instead."),console.warn("Read about changeRoute in: https://github.com/mercadona/wrapito#changeRoute"),o.push(c,M)),i&&!o&&s(c),B(p,R);let k=n(C.createElement(oe,{...d}));if(r){let ne=r.setup?r.setup(r.userLib,se):r.userLib;return{...k,user:ne}}return{...k,user:void 0}},v=e=>{if(document.getElementById(e))return;let t=document.createElement("div");t.setAttribute("id",e),t.setAttribute("data-testid",e),document.body.appendChild(t)},We=e=>{e.forEach(t=>{v(t)})};var w=require("jest-diff"),U=(e,t)=>{let s=t?.host?`\u{1F32F} Wrapito: ${t?.host}${e} ain't got called`:`\u{1F32F} Wrapito: ${e} ain't got called`;return{pass:!1,message:()=>s}},T=(e,t,s)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${s} times, you expected ${t} times`}),S=(e,t)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch method does not match, expected ${e} received ${t??"none"}`}),$=(e,t)=>{let s=t.map(o=>(0,w.diff)(e,o)).join(`
7
7
 
8
8
  `);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch body does not match.
9
- ${n}`}},ee=(e,t)=>{let n=t.find(s=>e!==s);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Host request does not match, expected ${e} received ${n}`}},te=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),B=()=>({pass:!0,message:()=>"Test passing"}),ne=(e,t)=>{let n=t?.host?`\u{1F32F} Wrapito: ${t.host}${e} is called`:`\u{1F32F} Wrapito: ${e} is called`;return{pass:!0,message:()=>n}};var se=T(require("deep-equal"),1);var oe=()=>{let e=d().defaultHost;return e?.includes("http")?e:"https://default.com"},_e=(e="",t,n)=>t.includes(n)?t:e+t,q=e=>e instanceof Request,Ge=e=>q(e)?e.url:e,W=(e,t={method:"GET"})=>fetch.mock.calls.filter(([s])=>{let o=Ge(s),r=oe(),a=new URL(o,r),l=_e(t?.host,e,r),i=t?.host||r,u=new URL(l,i),p=a.pathname===u.pathname,m=a.search===u.search,c=a.host===u.host;return u.search?p&&m:t?.host?p&&c:p}),re=e=>e.flat(1).filter(q).map(t=>t.method),ae=e=>e.flat(1).filter(q).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),ie=e=>e.flat(1).filter(q).map(t=>new URL(t.url,oe()).hostname),ce=(e,t)=>e&&!t.includes(e),pe=(e,t)=>t.map(s=>(0,se.default)(e,s)).every(s=>s===!1),ue=(e,t)=>t.every(s=>s!==e),le=e=>e.length===0;var Ve=(e,t)=>{let n=W(e);if(le(n))return H(e);let s=re(n),o=t?.method;if(ce(o,s))return X(o,s);let r=ae(n),a=t?.body;if(!a)return te();if(pe(a,r))return Z(a,r);let l=ie(n),i=t?.host;return i&&ue(i,l)?ee(i,l):B()},Qe=(e,t={method:"GET"})=>W(e,t).length?ne(e,t):H(e,t),Je=(e,t,n={method:"GET"})=>{let s=W(e,n);return s.length!==t?K(e,t,s.length):B()},Ye={toHaveBeenFetched:Qe,toHaveBeenFetchedWith:Ve,toHaveBeenFetchedTimes:Je};0&&(module.exports={assertions,configure,getConfig,matchers,wrap});
9
+ ${s}`}},L=(e,t)=>{let s=t.find(o=>e!==o);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Host request does not match, expected ${e} received ${s}`}},j=(e,t)=>{let s=t.map(o=>(0,w.diff)(e,o)).join(`
10
+
11
+ `);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch headers do not match.
12
+ ${s}`}},F=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),W=()=>({pass:!0,message:()=>"Test passing"}),_=(e,t)=>{let s=t?.host?`\u{1F32F} Wrapito: ${t.host}${e} is called`:`\u{1F32F} Wrapito: ${e} is called`;return{pass:!0,message:()=>s}};var G=x(require("deep-equal"),1);var Q=()=>{let e=u().defaultHost;return e?.includes("http")?e:"https://default.com"},ke=(e="",t,s)=>t.includes(s)?t:e+t,l=e=>e instanceof Request,De=e=>l(e)?e.url:e,b=(e,t={method:"GET"})=>fetch.mock.calls.filter(([o])=>{let n=De(o),r=Q(),a=new URL(n,r),d=ke(t?.host,e,r),p=t?.host||r,c=new URL(d,p),i=a.pathname===c.pathname,R=a.search===c.search,M=a.host===c.host;return c.search?i&&R:t?.host?i&&M:i}),J=e=>e.flat(1).filter(l).map(t=>t.method),Y=e=>e.flat(1).filter(l).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),X=e=>e.flat(1).filter(l).map(t=>new URL(t.url,Q()).hostname),z=e=>e.flat(1).filter(l).map(t=>{let s={};return t.headers.forEach((o,n)=>{s[n]=o}),s}),K=(e,t)=>e&&!t.includes(e),V=(e,t)=>t.map(o=>(0,G.default)(e,o)).every(o=>o===!1),Z=(e,t)=>t.every(o=>o!==e),ee=(e,t)=>t.every(o=>Object.entries(e).some(([n,r])=>o[n.toLowerCase()]!==r)),te=e=>e.length===0;var Oe=(e,t)=>{let s=b(e);if(te(s))return U(e);let o=J(s),n=t?.method;if(K(n,o))return S(n,o);let r=Y(s),a=t?.body;if(!a)return F();if(V(a,r))return $(a,r);let d=X(s),p=t?.host;if(p&&Z(p,d))return L(p,d);let c=z(s),i=t?.headers;return i&&ee(i,c)?j(i,c):W()},He=(e,t={method:"GET"})=>b(e,t).length?_(e,t):U(e,t),Pe=(e,t,s={method:"GET"})=>{let o=b(e,s);return o.length!==t?T(e,t,o.length):W()},Ae={toHaveBeenFetched:He,toHaveBeenFetchedWith:Oe,toHaveBeenFetchedTimes:Pe};0&&(module.exports={assertions,configure,getConfig,matchers,wrap});
package/dist/index.mjs CHANGED
@@ -1,9 +1,12 @@
1
- import*as _ from"react";import x from"chalk";import S from"object-hash";import{render as ae}from"@testing-library/react";var W={defaultHost:"",extend:{},mount:ae,changeRoute:e=>window.history.replaceState(null,"",e)};function Be(e){W={...W,...e}}var f=()=>({...W});var H=e=>t=>{let{method:n="GET",path:s,host:o=f().defaultHost,requestBody:r=void 0,catchParams:a}=t,l=o+s,i=!f().handleQueryParams||a,u=S({url:i?l:l.split("?")[0],method:n.toUpperCase(),requestBody:r}),p;return"_bodyInit"in e&&e._bodyInit!==void 0&&(p=JSON.parse(e._bodyInit)),S({url:i?e.url:e.url.split("?")[0],method:e.method,requestBody:p})===u};function O(e,t){if(!e)throw new Error(t)}function I(e,t){return typeof t===e}function ie(e){return e instanceof Promise}function v(e,t,n){Object.defineProperty(e,t,n)}function w(e,t,n){Object.defineProperty(e,t,{value:n})}var M=Symbol.for("tinyspy:spy"),ce=new Set,pe=e=>{e.called=!1,e.callCount=0,e.calls=[],e.results=[],e.next=[]},ue=e=>(v(e,M,{value:{reset:()=>pe(e[M])}}),e[M]),T=e=>e[M]||ue(e);function le(e){O(I("function",e)||I("undefined",e),"cannot spy on a non-function value");let t=function(...s){let o=T(t);o.called=!0,o.callCount++,o.calls.push(s);let r=o.next.shift();if(r){o.results.push(r);let[u,p]=r;if(u==="ok")return p;throw p}let a,l="ok";if(o.impl)try{new.target?a=Reflect.construct(o.impl,s,new.target):a=o.impl.apply(this,s),l="ok"}catch(u){throw a=u,l="error",o.results.push([l,u]),u}let i=[l,a];if(ie(a)){let u=a.then(p=>i[1]=p).catch(p=>{throw i[0]="error",i[1]=p,p});Object.assign(u,a),a=u}return o.results.push(i),a};w(t,"_isMockFunction",!0),w(t,"length",e?e.length:0),w(t,"name",e&&e.name||"spy");let n=T(t);return n.reset(),n.impl=e,t}var B=(e,t)=>Object.getOwnPropertyDescriptor(e,t),j=(e,t)=>{t!=null&&typeof t=="function"&&t.prototype!=null&&Object.setPrototypeOf(e.prototype,t.prototype)};function N(e,t,n){O(!I("undefined",e),"spyOn could not find an object to spy upon"),O(I("object",e)||I("function",e),"cannot spyOn on a primitive value");let[s,o]=(()=>{if(!I("object",t))return[t,"value"];if("getter"in t&&"setter"in t)throw new Error("cannot spy on both getter and setter");if("getter"in t)return[t.getter,"get"];if("setter"in t)return[t.setter,"set"];throw new Error("specify getter or setter to spy on")})(),r=B(e,s),a=Object.getPrototypeOf(e),l=a&&B(a,s),i=r||l;O(i||s in e,`${String(s)} does not exist`);let u=!1;o==="value"&&i&&!i.value&&i.get&&(o="get",u=!0,n=i.get());let p;i?p=i[o]:o!=="value"?p=()=>e[s]:p=e[s],n||(n=p);let m=le(n);o==="value"&&j(m,p);let c=h=>{let{value:k,...q}=i||{configurable:!0,writable:!0};o!=="value"&&delete q.writable,q[o]=h,v(e,s,q)},g=()=>i?v(e,s,i):c(p),d=m[M];return w(d,"restore",g),w(d,"getOriginal",()=>u?p():p),w(d,"willCall",h=>(d.impl=h,m)),c(u?()=>(j(m,n),m):m),ce.add(m),m}var de=new Set,he=0;function fe(e){let t=e,n,s=[],o=[],r=T(e),a={get calls(){return r.calls},get instances(){return s},get invocationCallOrder(){return o},get results(){return r.results.map(([c,g])=>({type:c==="error"?"throw":"return",value:g}))},get lastCall(){return r.calls[r.calls.length-1]}},l=[],i=!1;function u(...c){return s.push(this),o.push(++he),(i?n:l.shift()||n||r.getOriginal()||(()=>{})).apply(this,c)}let p=t.name;t.getMockName=()=>p||"vi.fn()",t.mockName=c=>(p=c,t),t.mockClear=()=>(r.reset(),s=[],o=[],t),t.mockReset=()=>(t.mockClear(),n=()=>{},l=[],t),t.mockRestore=()=>(t.mockReset(),r.restore(),n=void 0,t),t.getMockImplementation=()=>n,t.mockImplementation=c=>(n=c,r.willCall(u),t),t.mockImplementationOnce=c=>(l.push(c),t);function m(c,g){let d=n;n=c,r.willCall(u),i=!0;let h=()=>{n=d,i=!1},k=g();return k instanceof Promise?k.then(()=>(h(),t)):(h(),t)}return t.withImplementation=m,t.mockReturnThis=()=>t.mockImplementation(function(){return this}),t.mockReturnValue=c=>t.mockImplementation(()=>c),t.mockReturnValueOnce=c=>t.mockImplementationOnce(()=>c),t.mockResolvedValue=c=>t.mockImplementation(()=>Promise.resolve(c)),t.mockResolvedValueOnce=c=>t.mockImplementationOnce(()=>Promise.resolve(c)),t.mockRejectedValue=c=>t.mockImplementation(()=>Promise.reject(c)),t.mockRejectedValueOnce=c=>t.mockImplementationOnce(()=>Promise.reject(c)),Object.defineProperty(t,"mock",{get:()=>a}),r.willCall(u),de.add(t),t}var E=e=>fe(N({spy:e||(()=>{})},"spy"));beforeEach(()=>{global.window.fetch=E()});afterEach(()=>{global.window.fetch.mockReset()});var ge=async()=>{let e={json:()=>Promise.resolve(),status:200,ok:!0,headers:new Headers({"Content-Type":"application/json"})};return Promise.resolve(e)},$=async e=>{let{responseBody:t,status:n=200,headers:s={},delay:o}=e,r={json:()=>Promise.resolve(t),status:n,ok:n>=200&&n<=299,headers:new Headers({"Content-Type":"application/json",...s})};return o?new Promise(a=>setTimeout(()=>a(r),o)):Promise.resolve(r)},ye=e=>console.warn(`
2
- ${x.white.bold.bgRed("wrapito")} ${x.redBright.bold("cannot find any mock matching:")}
3
- ${x.greenBright(`URL: ${e.url}`)}
4
- ${x.greenBright(`METHOD: ${e.method?.toLowerCase()}`)}
5
- ${x.greenBright(`REQUEST BODY: ${e._bodyInit}`)}
6
- `),L=async(e,t,n)=>{let s=e.find(H(t));if(!s)return n&&ye(t),ge();let{multipleResponses:o}=s;if(!o)return $(s);let r=o.find(a=>!a.hasBeenReturned);if(!r){n&&Re(s);return}return r.hasBeenReturned=!0,$(r)},F=(e=[],t=!1)=>{global.window.fetch.mockImplementation((s,o)=>{if(typeof s=="string"){let a=new Request(s,o);return L(e,a,t)}return L(e,s,t)})},Re=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,n=x.greenBright(t);console.warn(n)};var A,y=e=>{A={...A,...e}},R=()=>({...A});beforeEach(()=>{global.fetch=E()});afterEach(()=>{global.fetch.mockReset()});var Ze=e=>(y({Component:e,responses:[],props:{},path:"",hasPath:!1,interactionConfig:void 0,debug:process.env.npm_config_debugRequests==="true"}),b()),b=()=>{let e=xe();return{withProps:ke,withNetwork:Oe,withInteraction:Me,atPath:Te,debugRequests:Ee,mount:Pe,...e}},be=e=>{let t=R(),n=[...t.responses,...e];y({...t,responses:n})},Ie=(e,t)=>(t({addResponses:be},e),b()),we=(e,t)=>{let{extend:n}=f(),s=n[t];return{...e,[t]:(...o)=>Ie(o,s)}},xe=()=>{let{extend:e}=f();return Object.keys(e).reduce(we,{})},ke=e=>{let t=R();return y({...t,props:e}),b()},Me=e=>{let t=R();return y({...t,interactionConfig:e}),b()},Oe=(e=[])=>{let t=R(),n=Array.isArray(e)?e:[e];return y({...t,responses:[...t.responses,...n]}),b()},Te=(e,t)=>{let n=R();return y({...n,historyState:t,path:e,hasPath:!0}),b()},Ee=()=>{let e=R();return y({...e,debug:!0}),b()},Pe=()=>{let{portal:e,portals:t,changeRoute:n,history:s,mount:o,interaction:r}=f(),{Component:a,props:l,responses:i,path:u,hasPath:p,debug:m,historyState:c,interactionConfig:g}=R(),d=a;e&&G(e),t&&Ue(t),p&&s&&(console.warn("wrapito WARNING: history is DEPRECATED. Pass a changeRoute function to the config instead."),console.warn("Read about changeRoute in: https://github.com/mercadona/wrapito#changeRoute"),s.push(u,c)),p&&!s&&n(u),F(i,m);let h=o(_.createElement(d,{...l}));if(r){let k=r.setup?r.setup(r.userLib,g):r.userLib;return{...h,user:k}}return{...h,user:void 0}},G=e=>{if(document.getElementById(e))return;let t=document.createElement("div");t.setAttribute("id",e),t.setAttribute("data-testid",e),document.body.appendChild(t)},Ue=e=>{e.forEach(t=>{G(t)})};import{diff as qe}from"jest-diff";var C=(e,t)=>{let n=t?.host?`\u{1F32F} Wrapito: ${t?.host}${e} ain't got called`:`\u{1F32F} Wrapito: ${e} ain't got called`;return{pass:!1,message:()=>n}},V=(e,t,n)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${n} times, you expected ${t} times`}),Q=(e,t)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch method does not match, expected ${e} received ${t??"none"}`}),J=(e,t)=>{let n=t.map(s=>qe(e,s)).join(`
1
+ import*as O from"react";import f from"chalk";import w from"object-hash";import{render as Z}from"@testing-library/react";var b={defaultHost:"",extend:{},mount:Z,changeRoute:e=>window.history.replaceState(null,"",e)};function Ie(e){b={...b,...e}}var d=()=>({...b});var U=e=>t=>{let{method:s="GET",path:o,host:r=d().defaultHost,requestBody:n=void 0,catchParams:a}=t,u=r+o,p=!d().handleQueryParams||a,c=w({url:p?u:u.split("?")[0],method:s.toUpperCase(),requestBody:n}),i;return"_bodyInit"in e&&e._bodyInit!==void 0&&(i=JSON.parse(e._bodyInit)),w({url:p?e.url:e.url.split("?")[0],method:e.method,requestBody:i})===c};var ee=async()=>{let e={json:()=>Promise.resolve(),status:200,ok:!0,headers:new Headers({"Content-Type":"application/json"})};return Promise.resolve(e)},W=async e=>{let{responseBody:t,status:s=200,headers:o={},delay:r}=e,n={json:()=>Promise.resolve(t),status:s,ok:s>=200&&s<=299,headers:new Headers({"Content-Type":"application/json",...o})};return r?new Promise(a=>setTimeout(()=>a(n),r)):Promise.resolve(n)},te=e=>console.warn(`
2
+ ${f.white.bold.bgRed("wrapito")} ${f.redBright.bold("cannot find any mock matching:")}
3
+ ${f.greenBright(`URL: ${e.url}`)}
4
+ ${f.greenBright(`METHOD: ${e.method?.toLowerCase()}`)}
5
+ ${f.greenBright(`REQUEST BODY: ${e._bodyInit}`)}
6
+ `),k=async(e,t,s)=>{let o=e.find(U(t));if(!o)return s&&te(t),ee();let{multipleResponses:r}=o;if(!r)return W(o);let n=r.find(a=>!a.hasBeenReturned);if(!n){s&&se(o);return}return n.hasBeenReturned=!0,W(n)},D=(e=[],t=!1)=>{global.window.fetch.mockImplementation((o,r)=>{if(typeof o=="string"){let a=new Request(o,r);return k(e,a,t)}return k(e,o,t)})},se=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,s=f.greenBright(t);console.warn(s)};var M,h=e=>{M={...M,...e}},m=()=>({...M});import{createMockInstance as oe}from"@vitest/spy";beforeEach(()=>{global.fetch=oe()});afterEach(()=>{global.fetch.mockReset()});var Ce=e=>(h({Component:e,responses:[],props:{},path:"",hasPath:!1,interactionConfig:void 0,debug:process.env.npm_config_debugRequests==="true"}),g()),g=()=>{let e=ie();return{withProps:ce,withNetwork:ue,withInteraction:pe,atPath:de,debugRequests:he,mount:me,...e}},ne=e=>{let t=m(),s=[...t.responses,...e];h({...t,responses:s})},re=(e,t)=>(t({addResponses:ne},e),g()),ae=(e,t)=>{let{extend:s}=d(),o=s[t];return{...e,[t]:(...r)=>re(r,o)}},ie=()=>{let{extend:e}=d();return Object.keys(e).reduce(ae,{})},ce=e=>{let t=m();return h({...t,props:e}),g()},pe=e=>{let t=m();return h({...t,interactionConfig:e}),g()},ue=(e=[])=>{let t=m(),s=Array.isArray(e)?e:[e];return h({...t,responses:[...t.responses,...s]}),g()},de=(e,t)=>{let s=m();return h({...s,historyState:t,path:e,hasPath:!0}),g()},he=()=>{let e=m();return h({...e,debug:!0}),g()},me=()=>{let{portal:e,portals:t,changeRoute:s,history:o,mount:r,interaction:n}=d(),{Component:a,props:u,responses:p,path:c,hasPath:i,debug:R,historyState:x,interactionConfig:z}=m(),K=a;e&&H(e),t&&ge(t),i&&o&&(console.warn("wrapito WARNING: history is DEPRECATED. Pass a changeRoute function to the config instead."),console.warn("Read about changeRoute in: https://github.com/mercadona/wrapito#changeRoute"),o.push(c,x)),i&&!o&&s(c),D(p,R);let E=r(O.createElement(K,{...u}));if(n){let V=n.setup?n.setup(n.userLib,z):n.userLib;return{...E,user:V}}return{...E,user:void 0}},H=e=>{if(document.getElementById(e))return;let t=document.createElement("div");t.setAttribute("id",e),t.setAttribute("data-testid",e),document.body.appendChild(t)},ge=e=>{e.forEach(t=>{H(t)})};import{diff as P}from"jest-diff";var I=(e,t)=>{let s=t?.host?`\u{1F32F} Wrapito: ${t?.host}${e} ain't got called`:`\u{1F32F} Wrapito: ${e} ain't got called`;return{pass:!1,message:()=>s}},A=(e,t,s)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${s} times, you expected ${t} times`}),B=(e,t)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch method does not match, expected ${e} received ${t??"none"}`}),C=(e,t)=>{let s=t.map(o=>P(e,o)).join(`
7
7
 
8
8
  `);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch body does not match.
9
- ${n}`}},Y=(e,t)=>{let n=t.find(s=>e!==s);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Host request does not match, expected ${e} received ${n}`}},z=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),D=()=>({pass:!0,message:()=>"Test passing"}),K=(e,t)=>{let n=t?.host?`\u{1F32F} Wrapito: ${t.host}${e} is called`:`\u{1F32F} Wrapito: ${e} is called`;return{pass:!0,message:()=>n}};import We from"deep-equal";var X=()=>{let e=f().defaultHost;return e?.includes("http")?e:"https://default.com"},ve=(e="",t,n)=>t.includes(n)?t:e+t,P=e=>e instanceof Request,Ae=e=>P(e)?e.url:e,U=(e,t={method:"GET"})=>fetch.mock.calls.filter(([s])=>{let o=Ae(s),r=X(),a=new URL(o,r),l=ve(t?.host,e,r),i=t?.host||r,u=new URL(l,i),p=a.pathname===u.pathname,m=a.search===u.search,c=a.host===u.host;return u.search?p&&m:t?.host?p&&c:p}),Z=e=>e.flat(1).filter(P).map(t=>t.method),ee=e=>e.flat(1).filter(P).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),te=e=>e.flat(1).filter(P).map(t=>new URL(t.url,X()).hostname),ne=(e,t)=>e&&!t.includes(e),se=(e,t)=>t.map(s=>We(e,s)).every(s=>s===!1),oe=(e,t)=>t.every(s=>s!==e),re=e=>e.length===0;var Ce=(e,t)=>{let n=U(e);if(re(n))return C(e);let s=Z(n),o=t?.method;if(ne(o,s))return Q(o,s);let r=ee(n),a=t?.body;if(!a)return z();if(se(a,r))return J(a,r);let l=te(n),i=t?.host;return i&&oe(i,l)?Y(i,l):D()},De=(e,t={method:"GET"})=>U(e,t).length?K(e,t):C(e,t),Se=(e,t,n={method:"GET"})=>{let s=U(e,n);return s.length!==t?V(e,t,s.length):D()},ct={toHaveBeenFetched:De,toHaveBeenFetchedWith:Ce,toHaveBeenFetchedTimes:Se};export{ct as assertions,Be as configure,f as getConfig,ct as matchers,Ze as wrap};
9
+ ${s}`}},N=(e,t)=>{let s=t.find(o=>e!==o);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Host request does not match, expected ${e} received ${s}`}},v=(e,t)=>{let s=t.map(o=>P(e,o)).join(`
10
+
11
+ `);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch headers do not match.
12
+ ${s}`}},T=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),q=()=>({pass:!0,message:()=>"Test passing"}),S=(e,t)=>{let s=t?.host?`\u{1F32F} Wrapito: ${t.host}${e} is called`:`\u{1F32F} Wrapito: ${e} is called`;return{pass:!0,message:()=>s}};import fe from"deep-equal";var $=()=>{let e=d().defaultHost;return e?.includes("http")?e:"https://default.com"},le=(e="",t,s)=>t.includes(s)?t:e+t,l=e=>e instanceof Request,Re=e=>l(e)?e.url:e,y=(e,t={method:"GET"})=>fetch.mock.calls.filter(([o])=>{let r=Re(o),n=$(),a=new URL(r,n),u=le(t?.host,e,n),p=t?.host||n,c=new URL(u,p),i=a.pathname===c.pathname,R=a.search===c.search,x=a.host===c.host;return c.search?i&&R:t?.host?i&&x:i}),L=e=>e.flat(1).filter(l).map(t=>t.method),j=e=>e.flat(1).filter(l).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),F=e=>e.flat(1).filter(l).map(t=>new URL(t.url,$()).hostname),_=e=>e.flat(1).filter(l).map(t=>{let s={};return t.headers.forEach((o,r)=>{s[r]=o}),s}),G=(e,t)=>e&&!t.includes(e),Q=(e,t)=>t.map(o=>fe(e,o)).every(o=>o===!1),J=(e,t)=>t.every(o=>o!==e),Y=(e,t)=>t.every(o=>Object.entries(e).some(([r,n])=>o[r.toLowerCase()]!==n)),X=e=>e.length===0;var ye=(e,t)=>{let s=y(e);if(X(s))return I(e);let o=L(s),r=t?.method;if(G(r,o))return B(r,o);let n=j(s),a=t?.body;if(!a)return T();if(Q(a,n))return C(a,n);let u=F(s),p=t?.host;if(p&&J(p,u))return N(p,u);let c=_(s),i=t?.headers;return i&&Y(i,c)?v(i,c):q()},xe=(e,t={method:"GET"})=>y(e,t).length?S(e,t):I(e,t),be=(e,t,s={method:"GET"})=>{let o=y(e,s);return o.length!==t?A(e,t,o.length):q()},_e={toHaveBeenFetched:xe,toHaveBeenFetchedWith:ye,toHaveBeenFetchedTimes:be};export{_e as assertions,Ie as configure,d as getConfig,_e as matchers,Ce as wrap};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrapito",
3
- "version": "13.2.2",
3
+ "version": "13.3.0-beta10",
4
4
  "description": "🌯 🌯 Wrap you tests so that you can test both behaviour and components with less effort.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -52,6 +52,7 @@
52
52
  },
53
53
  "homepage": "https://github.com/mercadona/wrapito#readme",
54
54
  "dependencies": {
55
+ "@vitest/spy": "^4.0.15",
55
56
  "chalk": "^5.6.2",
56
57
  "deep-equal": "^2.2.3",
57
58
  "jest-diff": "^29.7.0",
@@ -66,9 +67,9 @@
66
67
  "@types/object-hash": "^3.0.6",
67
68
  "@types/react": "^19.1.8",
68
69
  "@types/react-router-dom": "^5.3.3",
69
- "@vitest/coverage-istanbul": "^1.1.0",
70
+ "@vitest/coverage-istanbul": "^3.2.4",
70
71
  "eslint": "^8.56.0",
71
- "eslint-config-prettier": "^9.1.0",
72
+ "eslint-config-prettier": "^10.1.8",
72
73
  "eslint-config-react-app": "^7.0.1",
73
74
  "eslint-plugin-prettier": "^5.1.1",
74
75
  "eslint-plugin-react": "^7.33.2",
@@ -84,7 +85,7 @@
84
85
  "tinyspy": "^2.2.1",
85
86
  "tsup": "^8.5.1",
86
87
  "typescript": "^5.9.3",
87
- "vitest": "^1.1.0"
88
+ "vitest": "^3.2.4"
88
89
  },
89
90
  "peerDependencies": {
90
91
  "@testing-library/jest-dom": ">=5.16.4",