wrapito 13.0.0-beta2 → 13.0.0

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
@@ -6,6 +6,21 @@ Wrap you tests so that you can test both behaviour and components with less effo
6
6
 
7
7
  This version is agnostic and compatible with both [jest](https://jestjs.io/) and [vitest](https://vitest.dev/).
8
8
 
9
+ ### Note:
10
+
11
+ From the version 13 wrapito is compatible with the new version of React and requires such versions of dependencies:
12
+
13
+ ```
14
+ "peerDependencies": {
15
+ "@testing-library/jest-dom": ">=5.16.4",
16
+ "@testing-library/react": ">=14.0.0",
17
+ "react-dom": ">=18.0.0",
18
+ "react": ">=18.0.0"
19
+ }
20
+ ```
21
+
22
+ If your project uses React <=18.0.0, you can use wrapito <=12, but we extremely recommend to migrate to newest versions, because we are not maintaining legacy dependencies.
23
+
9
24
  ## 🎯 Motivation
10
25
 
11
26
  As we are more focused on user interactions than implementation details. In order to test all the user interactions that
@@ -21,8 +36,6 @@ As we test our app we will be in two different scenarios where:
21
36
  returns (renders) the expected result.
22
37
 
23
38
  In general, if you want to test behaviour, you need to simulate external actions from user or from http responses.
24
- Most of the existing testing libraries give you control of the user actions and thats why we just ask you to set in the
25
- config what is the `render` function of your testing library.
26
39
  Unfortunately, there aren't so many options when it comes to manage http requests and responses in the tests.
27
40
  To give the mounted component context about which path is the current path where the app should be mounted, what props
28
41
  does the component receive, what http requests will respond with which results or where should the portal be mounted we
@@ -46,40 +59,29 @@ const myWrappedComponent = wrap(MyComponent).mount()
46
59
 
47
60
  ## 👣 Initial setup
48
61
 
49
- Because 🌯 `wrapito` doesn't want to know anything about how the components are mounted in the project that uses it, we
50
- can specify how we will `mount` our components by passing the rendering/mounting function of our library of preference.
51
- This way we make `wrapito` a little bit more agnostic. For example `setup.wrapito.js`
62
+ In the latest version of 🌯 `wrapito` passing the rendering/mounting function is optional, because we use `render` from `@testing-library/react` by default.
63
+
64
+ If one or more of your components use a `react portal` in any way, you will need to specify the `id` of the node where
65
+ it will be added.
66
+
67
+ To configure wrapito we recommend adding a setupTests.tsx file and adding there all your custom configs and extensions.
52
68
 
53
69
  ```js
54
- import { render } from '@testing-library/react'
55
70
  import { configure } from 'wrapito'
56
71
 
57
72
  configure({
58
- mount: render,
73
+ defaultHost: 'your-host-path',
74
+ portal: 'modal-root',
75
+ extend: {
76
+ /* Here you can group network calls to reuse them in your tests */
77
+ },
59
78
  })
60
79
  ```
61
80
 
62
- and add the previous file in `jest.config.json`
63
-
64
- ```js
65
- "setupFiles"
66
- :
67
- [
68
- "<rootDir>/config/jest/setup.wrapito.js"
69
- ],
70
- ```
71
-
72
- If one or more of your components use a `react portal` in any way, you will need to specify the `id` of the node where
73
- it will be added:
81
+ Add this line in your project setup (vite/cra):
74
82
 
75
83
  ```js
76
- import { render } from '@testing-library/react'
77
- import { configure } from 'wrapito'
78
-
79
- configure({
80
- mount: render,
81
- portal: 'modal-root',
82
- })
84
+ setupFiles: ['./src/setupTests.tsx']
83
85
  ```
84
86
 
85
87
  ## 🏰 Builder API
@@ -92,8 +94,7 @@ given request, done by the production code, is not set up in the `responses obje
92
94
  #### withNetwork
93
95
 
94
96
  By using this feature you can configure the responses for your `http requests`. If your component is making a request
95
- that is not set up in the `responses object`, it will not be validated and it will return an empty response with code
96
- 200.
97
+ that is not set up in the `responses object`, it will not be validated and it will return an empty response with code 200.
97
98
 
98
99
  ```js
99
100
  import { wrap } from 'wrapito'
@@ -101,16 +102,14 @@ import { wrap } from 'wrapito'
101
102
  const responses = {
102
103
  host: 'my-host',
103
104
  method: 'get',
104
- path: '/path/to/get/a/single/product/,
105
+ path: '/path/to/get/a/single/product/',
105
106
  responseBody: { id: 1, name: 'hummus' },
106
107
  status: 200,
107
108
  catchParams: true,
108
109
  delay: 500,
109
110
  }
110
111
 
111
- wrap(MyComponent)
112
- .withNetwork(responses)
113
- .mount()
112
+ wrap(MyComponent).withNetwork(responses).mount()
114
113
  ```
115
114
 
116
115
  You can specify the default `host` via configuration:
@@ -146,21 +145,19 @@ import { wrap } from 'wrapito'
146
145
 
147
146
  const responses = [
148
147
  {
149
- path: '/path/to/get/the/products/list/,
148
+ path: '/path/to/get/the/products/list/',
150
149
  responseBody: [
151
150
  { id: 1, name: 'hummus' },
152
151
  { id: 2, name: 'guacamole' },
153
- ]
152
+ ],
154
153
  },
155
154
  {
156
- path: '/path/to/get/a/single/product/,
155
+ path: '/path/to/get/a/single/product/',
157
156
  responseBody: { id: 1, name: 'hummus' },
158
157
  },
159
158
  ]
160
159
 
161
- wrap(MyComponent)
162
- .withNetwork(responses)
163
- .mount()
160
+ wrap(MyComponent).withNetwork(responses).mount()
164
161
  ```
165
162
 
166
163
  There might be cases where one request is called several times and we want it to return different responses. An example
@@ -322,6 +319,10 @@ git push origin v1.0.5
322
319
 
323
320
  This will run a workflow in github that will publish this version for you.
324
321
 
322
+ ### Release beta versions
323
+
324
+ WARNING: DO NOT MERGE YOUR PR IF YOU WANT TO DO A BETA RELEASE, SINCE THE CHANGES ARE NOT FULLY TRUSTED THEY SHOULD NOT GO TO MASTER
325
+
325
326
  If you need to release beta versions to test things, you may do so with the -beta tag. E.g:
326
327
 
327
328
  ```
package/dist/index.d.cts CHANGED
@@ -63,6 +63,7 @@ interface Config {
63
63
  changeRoute: (path: string) => void;
64
64
  history?: BrowserHistory;
65
65
  portal?: string;
66
+ portals?: string[];
66
67
  handleQueryParams?: boolean;
67
68
  }
68
69
  interface BrowserHistory extends History {
package/dist/index.d.ts CHANGED
@@ -63,6 +63,7 @@ interface Config {
63
63
  changeRoute: (path: string) => void;
64
64
  history?: BrowserHistory;
65
65
  portal?: string;
66
+ portals?: string[];
66
67
  handleQueryParams?: boolean;
67
68
  }
68
69
  interface BrowserHistory extends History {
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- "use strict";var ie=Object.create;var E=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ue=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var me=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},$=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of pe(t))!le.call(e,o)&&o!==n&&E(e,o,{get:()=>t[o],enumerable:!(s=ce(t,o))||s.enumerable});return e};var M=(e,t,n)=>(n=e!=null?ie(ue(e)):{},$(t||!e||!e.__esModule?E(n,"default",{value:e,enumerable:!0}):n,e)),de=e=>$(E({},"__esModule",{value:!0}),e);var Ge={};me(Ge,{assertions:()=>_e,configure:()=>he,getConfig:()=>d,matchers:()=>_e,wrap:()=>Ie});module.exports=de(Ge);var J=M(require("react"),1);var f=M(require("chalk"),1);var A=M(require("object-hash"),1);var D=require("@testing-library/react"),C={defaultHost:"",extend:{},mount:D.render,changeRoute:e=>window.history.replaceState(null,"",e)};function he(e){C={...C,...e}}var d=()=>({...C});var F=e=>t=>{let{method:n="GET",path:s,host:o=d().defaultHost,requestBody:r=void 0,catchParams:a}=t,l=o+s,p=!d().handleQueryParams||a,u=(0,A.default)({url:p?l:l.split("?")[0],method:n.toUpperCase(),requestBody:r}),i;return"_bodyInit"in e&&e._bodyInit!==void 0&&(i=JSON.parse(e._bodyInit)),(0,A.default)({url:p?e.url:e.url.split("?")[0],method:e.method,requestBody:i})===u};function P(e,t){if(!e)throw new Error(t)}function b(e,t){return typeof t===e}function fe(e){return e instanceof Promise}function B(e,t,n){Object.defineProperty(e,t,n)}function k(e,t,n){Object.defineProperty(e,t,{value:n})}var T=Symbol.for("tinyspy:spy"),ge=new Set,ye=e=>{e.called=!1,e.callCount=0,e.calls=[],e.results=[],e.next=[]},Re=e=>(B(e,T,{value:{reset:()=>ye(e[T])}}),e[T]),I=e=>e[T]||Re(e);function we(e){P(b("function",e)||b("undefined",e),"cannot spy on a non-function value");let t=function(...s){let o=I(t);o.called=!0,o.callCount++,o.calls.push(s);let r=o.next.shift();if(r){o.results.push(r);let[u,i]=r;if(u==="ok")return i;throw i}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 p=[l,a];if(fe(a)){let u=a.then(i=>p[1]=i).catch(i=>{throw p[0]="error",p[1]=i,i});Object.assign(u,a),a=u}return o.results.push(p),a};k(t,"_isMockFunction",!0),k(t,"length",e?e.length:0),k(t,"name",e&&e.name||"spy");let n=I(t);return n.reset(),n.impl=e,t}var U=(e,t)=>Object.getOwnPropertyDescriptor(e,t),L=(e,t)=>{t!=null&&typeof t=="function"&&t.prototype!=null&&Object.setPrototypeOf(e.prototype,t.prototype)};function _(e,t,n){P(!b("undefined",e),"spyOn could not find an object to spy upon"),P(b("object",e)||b("function",e),"cannot spyOn on a primitive value");let[s,o]=(()=>{if(!b("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=U(e,s),a=Object.getPrototypeOf(e),l=a&&U(a,s),p=r||l;P(p||s in e,`${String(s)} does not exist`);let u=!1;o==="value"&&p&&!p.value&&p.get&&(o="get",u=!0,n=p.get());let i;p?i=p[o]:o!=="value"?i=()=>e[s]:i=e[s],n||(n=i);let m=we(n);o==="value"&&L(m,i);let c=w=>{let{value:q,...v}=p||{configurable:!0,writable:!0};o!=="value"&&delete v.writable,v[o]=w,B(e,s,v)},R=()=>p?B(e,s,p):c(i),h=m[T];return k(h,"restore",R),k(h,"getOriginal",()=>u?i():i),k(h,"willCall",w=>(h.impl=w,m)),c(u?()=>(L(m,n),m):m),ge.add(m),m}var ke=new Set,xe=0;function Te(e){let t=e,n,s=[],o=[],r=I(e),a={get calls(){return r.calls},get instances(){return s},get invocationCallOrder(){return o},get results(){return r.results.map(([c,R])=>({type:c==="error"?"throw":"return",value:R}))},get lastCall(){return r.calls[r.calls.length-1]}},l=[],p=!1;function u(...c){return s.push(this),o.push(++xe),(p?n:l.shift()||n||r.getOriginal()||(()=>{})).apply(this,c)}let i=t.name;t.getMockName=()=>i||"vi.fn()",t.mockName=c=>(i=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,R){let h=n;n=c,r.willCall(u),p=!0;let w=()=>{n=h,p=!1},q=R();return q instanceof Promise?q.then(()=>(w(),t)):(w(),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),ke.add(t),t}var O=e=>Te(_({spy:e||(()=>{})},"spy"));beforeEach(()=>{global.window.fetch=O()});afterEach(()=>{global.window.fetch.mockReset()});var Ee=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)},Me=e=>console.warn(`
1
+ "use strict";var me=Object.create;var T=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,ge=Object.prototype.hasOwnProperty;var ye=(e,t)=>{for(var s in t)T(e,s,{get:t[s],enumerable:!0})},$=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of he(t))!ge.call(e,o)&&o!==s&&T(e,o,{get:()=>t[o],enumerable:!(n=de(t,o))||n.enumerable});return e};var E=(e,t,s)=>(s=e!=null?me(fe(e)):{},$(t||!e||!e.__esModule?T(s,"default",{value:e,enumerable:!0}):s,e)),Re=e=>$(T({},"__esModule",{value:!0}),e);var Ye={};ye(Ye,{assertions:()=>Je,configure:()=>we,getConfig:()=>d,matchers:()=>Je,wrap:()=>Ae});module.exports=Re(Ye);var J=E(require("react"),1);var f=E(require("chalk"),1);var H=E(require("object-hash"),1);var D=require("@testing-library/react"),C={defaultHost:"",extend:{},mount:D.render,changeRoute:e=>window.history.replaceState(null,"",e)};function we(e){C={...C,...e}}var d=()=>({...C});var U=e=>t=>{let{method:s="GET",path:n,host:o=d().defaultHost,requestBody:r=void 0,catchParams:a}=t,l=o+n,i=!d().handleQueryParams||a,u=(0,H.default)({url:i?l:l.split("?")[0],method:s.toUpperCase(),requestBody:r}),p;return"_bodyInit"in e&&e._bodyInit!==void 0&&(p=JSON.parse(e._bodyInit)),(0,H.default)({url:i?e.url:e.url.split("?")[0],method:e.method,requestBody:p})===u};function P(e,t){if(!e)throw new Error(t)}function b(e,t){return typeof t===e}function be(e){return e instanceof Promise}function B(e,t,s){Object.defineProperty(e,t,s)}function k(e,t,s){Object.defineProperty(e,t,{value:s})}var M=Symbol.for("tinyspy:spy"),ke=new Set,xe=e=>{e.called=!1,e.callCount=0,e.calls=[],e.results=[],e.next=[]},Me=e=>(B(e,M,{value:{reset:()=>xe(e[M])}}),e[M]),O=e=>e[M]||Me(e);function Te(e){P(b("function",e)||b("undefined",e),"cannot spy on a non-function value");let t=function(...n){let o=O(t);o.called=!0,o.callCount++,o.calls.push(n);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,n,new.target):a=o.impl.apply(this,n),l="ok"}catch(u){throw a=u,l="error",o.results.push([l,u]),u}let i=[l,a];if(be(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};k(t,"_isMockFunction",!0),k(t,"length",e?e.length:0),k(t,"name",e&&e.name||"spy");let s=O(t);return s.reset(),s.impl=e,t}var F=(e,t)=>Object.getOwnPropertyDescriptor(e,t),L=(e,t)=>{t!=null&&typeof t=="function"&&t.prototype!=null&&Object.setPrototypeOf(e.prototype,t.prototype)};function _(e,t,s){P(!b("undefined",e),"spyOn could not find an object to spy upon"),P(b("object",e)||b("function",e),"cannot spyOn on a primitive value");let[n,o]=(()=>{if(!b("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=F(e,n),a=Object.getPrototypeOf(e),l=a&&F(a,n),i=r||l;P(i||n in e,`${String(n)} does not exist`);let u=!1;o==="value"&&i&&!i.value&&i.get&&(o="get",u=!0,s=i.get());let p;i?p=i[o]:o!=="value"?p=()=>e[n]:p=e[n],s||(s=p);let m=Te(s);o==="value"&&L(m,p);let c=w=>{let{value:W,...A}=i||{configurable:!0,writable:!0};o!=="value"&&delete A.writable,A[o]=w,B(e,n,A)},R=()=>i?B(e,n,i):c(p),h=m[M];return k(h,"restore",R),k(h,"getOriginal",()=>u?p():p),k(h,"willCall",w=>(h.impl=w,m)),c(u?()=>(L(m,s),m):m),ke.add(m),m}var Pe=new Set,Oe=0;function qe(e){let t=e,s,n=[],o=[],r=O(e),a={get calls(){return r.calls},get instances(){return n},get invocationCallOrder(){return o},get results(){return r.results.map(([c,R])=>({type:c==="error"?"throw":"return",value:R}))},get lastCall(){return r.calls[r.calls.length-1]}},l=[],i=!1;function u(...c){return n.push(this),o.push(++Oe),(i?s:l.shift()||s||r.getOriginal()||(()=>{})).apply(this,c)}let p=t.name;t.getMockName=()=>p||"vi.fn()",t.mockName=c=>(p=c,t),t.mockClear=()=>(r.reset(),n=[],o=[],t),t.mockReset=()=>(t.mockClear(),s=()=>{},l=[],t),t.mockRestore=()=>(t.mockReset(),r.restore(),s=void 0,t),t.getMockImplementation=()=>s,t.mockImplementation=c=>(s=c,r.willCall(u),t),t.mockImplementationOnce=c=>(l.push(c),t);function m(c,R){let h=s;s=c,r.willCall(u),i=!0;let w=()=>{s=h,i=!1},W=R();return W instanceof Promise?W.then(()=>(w(),t)):(w(),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),Pe.add(t),t}var q=e=>qe(_({spy:e||(()=>{})},"spy"));beforeEach(()=>{global.window.fetch=q()});afterEach(()=>{global.window.fetch.mockReset()});var Ie=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:s=200,headers:n={},delay:o}=e,r={json:()=>Promise.resolve(t),status:s,ok:s>=200&&s<=299,headers:new Headers({"Content-Type":"application/json",...n})};return o?new Promise(a=>setTimeout(()=>a(r),o)):Promise.resolve(r)},ve=e=>console.warn(`
2
2
  ${f.default.white.bold.bgRed("wrapito")} ${f.default.redBright.bold("cannot find any mock matching:")}
3
3
  ${f.default.greenBright(`URL: ${e.url}`)}
4
4
  ${f.default.greenBright(`METHOD: ${e.method?.toLowerCase()}`)}
5
5
  ${f.default.greenBright(`REQUEST BODY: ${e._bodyInit}`)}
6
- `),V=async(e,t,n)=>{let s=e.find(F(t));if(!s)return n&&Me(t),Ee();let{multipleResponses:o}=s;if(!o)return G(s);let r=o.find(a=>!a.hasBeenReturned);if(!r){n&&Pe(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)})},Pe=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,n=f.default.greenBright(t);console.warn(n)};var j,g=e=>{j={...j,...e}},y=()=>({...j});beforeEach(()=>{global.fetch=O()});afterEach(()=>{global.fetch.mockReset()});var Ie=e=>(g({Component:e,responses:[],props:{},path:"",hasPath:!1,debug:process.env.npm_config_debugRequests==="true"}),x()),x=()=>{let e=ve();return{withProps:Ce,withNetwork:Ae,atPath:Be,debugRequests:je,mount:He,...e}},Oe=e=>{let t=y(),n=[...t.responses,...e];g({...t,responses:n})},We=(e,t)=>(t({addResponses:Oe},e),x()),qe=(e,t)=>{let{extend:n}=d(),s=n[t];return{...e,[t]:(...o)=>We(o,s)}},ve=()=>{let{extend:e}=d();return Object.keys(e).reduce(qe,{})},Ce=e=>{let t=y();return g({...t,props:e}),x()},Ae=(e=[])=>{let t=y(),n=Array.isArray(e)?e:[e];return g({...t,responses:[...t.responses,...n]}),x()},Be=(e,t)=>{let n=y();return g({...n,historyState:t,path:e,hasPath:!0}),x()},je=()=>{let e=y();return g({...e,debug:!0}),x()},He=()=>{let{portal:e,changeRoute:t,history:n,mount:s}=d(),{Component:o,props:r,responses:a,path:l,hasPath:p,debug:u,historyState:i}=y(),m=o;return e&&Se(e),p&&n&&(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"),n.push(l,i)),p&&!n&&t(l),Q(a,u),s(J.createElement(m,{...r}))},Se=e=>{if(document.getElementById(e))return;let t=document.createElement("div");t.setAttribute("id",e),document.body.appendChild(t)};var Y=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}},z=(e,t,n)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${n} times, you expected ${t} times`}),K=(e,t)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch method does not match, expected ${e} received ${t??"none"}`}),X=(e,t)=>{let n=t.map(s=>(0,Y.diff)(e,s)).join(`
6
+ `),V=async(e,t,s)=>{let n=e.find(U(t));if(!n)return s&&ve(t),Ie();let{multipleResponses:o}=n;if(!o)return G(n);let r=o.find(a=>!a.hasBeenReturned);if(!r){s&&We(n);return}return r.hasBeenReturned=!0,G(r)},Q=(e=[],t=!1)=>{global.window.fetch.mockImplementation((n,o)=>{if(typeof n=="string"){let a=new Request(n,o);return V(e,a,t)}return V(e,n,t)})},We=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,s=f.default.greenBright(t);console.warn(s)};var j,g=e=>{j={...j,...e}},y=()=>({...j});beforeEach(()=>{global.fetch=q()});afterEach(()=>{global.fetch.mockReset()});var Ae=e=>(g({Component:e,responses:[],props:{},path:"",hasPath:!1,debug:process.env.npm_config_debugRequests==="true"}),x()),x=()=>{let e=je();return{withProps:Ne,withNetwork:Se,atPath:$e,debugRequests:De,mount:Ue,...e}},Ce=e=>{let t=y(),s=[...t.responses,...e];g({...t,responses:s})},He=(e,t)=>(t({addResponses:Ce},e),x()),Be=(e,t)=>{let{extend:s}=d(),n=s[t];return{...e,[t]:(...o)=>He(o,n)}},je=()=>{let{extend:e}=d();return Object.keys(e).reduce(Be,{})},Ne=e=>{let t=y();return g({...t,props:e}),x()},Se=(e=[])=>{let t=y(),s=Array.isArray(e)?e:[e];return g({...t,responses:[...t.responses,...s]}),x()},$e=(e,t)=>{let s=y();return g({...s,historyState:t,path:e,hasPath:!0}),x()},De=()=>{let e=y();return g({...e,debug:!0}),x()},Ue=()=>{let{portal:e,portals:t,changeRoute:s,history:n,mount:o}=d(),{Component:r,props:a,responses:l,path:i,hasPath:u,debug:p,historyState:m}=y(),c=r;return e&&Y(e),t&&Fe(t),u&&n&&(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"),n.push(i,m)),u&&!n&&s(i),Q(l,p),o(J.createElement(c,{...a}))},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"),N=(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}},K=(e,t,s)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${s} 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 s=t.map(n=>(0,z.diff)(e,n)).join(`
7
7
 
8
8
  `);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch body does not match.
9
- ${n}`}},Z=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),S=()=>({pass:!0,message:()=>"Test passing"}),ee=(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 te=M(require("deep-equal"),1);var Ne=()=>{let e=d().defaultHost;return e?.includes("http")?e:"https://default.com"},$e=(e="",t,n)=>t.includes(n)?t:e+t,N=e=>e instanceof Request,De=e=>N(e)?e.url:e,W=(e,t={method:"GET"})=>fetch.mock.calls.filter(([s])=>{let o=De(s),r=Ne(),a=new URL(o,r),l=$e(t?.host,e,r),p=t?.host||r,u=new URL(l,p),i=a.pathname===u.pathname,m=a.search===u.search,c=a.host===u.host;return u.search?i&&m:t?.host?i&&c:i}),ne=e=>e.flat(1).filter(N).map(t=>t.method),se=e=>e.flat(1).filter(N).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),oe=(e,t)=>e&&!t.includes(e),re=(e,t)=>t.map(s=>(0,te.default)(e,s)).every(s=>s===!1),ae=e=>e.length===0;var Fe=(e,t)=>{let n=W(e);if(ae(n))return H(e);let s=ne(n),o=t?.method;if(oe(o,s))return K(o,s);let r=se(n),a=t?.body;return a?re(a,r)?X(a,r):S():Z()},Ue=(e,t={method:"GET"})=>W(e,t).length?ee(e,t):H(e,t),Le=(e,t,n={method:"GET"})=>{let s=W(e,n);return s.length!==t?z(e,t,s.length):S()},_e={toHaveBeenFetched:Ue,toHaveBeenFetchedWith:Fe,toHaveBeenFetchedTimes:Le};0&&(module.exports={assertions,configure,getConfig,matchers,wrap});
9
+ ${s}`}},ee=(e,t)=>{let s=t.find(n=>e!==n);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Host request does not match, expected ${e} received ${s}`}},te=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),S=()=>({pass:!0,message:()=>"Test passing"}),se=(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 ne=E(require("deep-equal"),1);var oe=()=>{let e=d().defaultHost;return e?.includes("http")?e:"https://default.com"},Le=(e="",t,s)=>t.includes(s)?t:e+t,I=e=>e instanceof Request,_e=e=>I(e)?e.url:e,v=(e,t={method:"GET"})=>fetch.mock.calls.filter(([n])=>{let o=_e(n),r=oe(),a=new URL(o,r),l=Le(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(I).map(t=>t.method),ae=e=>e.flat(1).filter(I).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),ie=e=>e.flat(1).filter(I).map(t=>new URL(t.url,oe()).hostname),ce=(e,t)=>e&&!t.includes(e),pe=(e,t)=>t.map(n=>(0,ne.default)(e,n)).every(n=>n===!1),ue=(e,t)=>t.every(n=>n!==e),le=e=>e.length===0;var Ge=(e,t)=>{let s=v(e);if(le(s))return N(e);let n=re(s),o=t?.method;if(ce(o,n))return X(o,n);let r=ae(s),a=t?.body;if(!a)return te();if(pe(a,r))return Z(a,r);let l=ie(s),i=t?.host;return i&&ue(i,l)?ee(i,l):S()},Ve=(e,t={method:"GET"})=>v(e,t).length?se(e,t):N(e,t),Qe=(e,t,s={method:"GET"})=>{let n=v(e,s);return n.length!==t?K(e,t,n.length):S()},Je={toHaveBeenFetched:Ve,toHaveBeenFetchedWith:Ge,toHaveBeenFetchedTimes:Qe};0&&(module.exports={assertions,configure,getConfig,matchers,wrap});
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
- import*as _ from"react";import k from"chalk";import H from"object-hash";import{render as te}from"@testing-library/react";var q={defaultHost:"",extend:{},mount:te,changeRoute:e=>window.history.replaceState(null,"",e)};function Ae(e){q={...q,...e}}var d=()=>({...q});var S=e=>t=>{let{method:n="GET",path:s,host:o=d().defaultHost,requestBody:r=void 0,catchParams:a}=t,l=o+s,p=!d().handleQueryParams||a,u=H({url:p?l:l.split("?")[0],method:n.toUpperCase(),requestBody:r}),i;return"_bodyInit"in e&&e._bodyInit!==void 0&&(i=JSON.parse(e._bodyInit)),H({url:p?e.url:e.url.split("?")[0],method:e.method,requestBody:i})===u};function E(e,t){if(!e)throw new Error(t)}function w(e,t){return typeof t===e}function ne(e){return e instanceof Promise}function v(e,t,n){Object.defineProperty(e,t,n)}function b(e,t,n){Object.defineProperty(e,t,{value:n})}var T=Symbol.for("tinyspy:spy"),se=new Set,oe=e=>{e.called=!1,e.callCount=0,e.calls=[],e.results=[],e.next=[]},re=e=>(v(e,T,{value:{reset:()=>oe(e[T])}}),e[T]),M=e=>e[T]||re(e);function ae(e){E(w("function",e)||w("undefined",e),"cannot spy on a non-function value");let t=function(...s){let o=M(t);o.called=!0,o.callCount++,o.calls.push(s);let r=o.next.shift();if(r){o.results.push(r);let[u,i]=r;if(u==="ok")return i;throw i}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 p=[l,a];if(ne(a)){let u=a.then(i=>p[1]=i).catch(i=>{throw p[0]="error",p[1]=i,i});Object.assign(u,a),a=u}return o.results.push(p),a};b(t,"_isMockFunction",!0),b(t,"length",e?e.length:0),b(t,"name",e&&e.name||"spy");let n=M(t);return n.reset(),n.impl=e,t}var N=(e,t)=>Object.getOwnPropertyDescriptor(e,t),$=(e,t)=>{t!=null&&typeof t=="function"&&t.prototype!=null&&Object.setPrototypeOf(e.prototype,t.prototype)};function D(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=N(e,s),a=Object.getPrototypeOf(e),l=a&&N(a,s),p=r||l;E(p||s in e,`${String(s)} does not exist`);let u=!1;o==="value"&&p&&!p.value&&p.get&&(o="get",u=!0,n=p.get());let i;p?i=p[o]:o!=="value"?i=()=>e[s]:i=e[s],n||(n=i);let m=ae(n);o==="value"&&$(m,i);let c=R=>{let{value:O,...W}=p||{configurable:!0,writable:!0};o!=="value"&&delete W.writable,W[o]=R,v(e,s,W)},y=()=>p?v(e,s,p):c(i),h=m[T];return b(h,"restore",y),b(h,"getOriginal",()=>u?i():i),b(h,"willCall",R=>(h.impl=R,m)),c(u?()=>($(m,n),m):m),se.add(m),m}var ce=new Set,pe=0;function ue(e){let t=e,n,s=[],o=[],r=M(e),a={get calls(){return r.calls},get instances(){return s},get invocationCallOrder(){return o},get results(){return r.results.map(([c,y])=>({type:c==="error"?"throw":"return",value:y}))},get lastCall(){return r.calls[r.calls.length-1]}},l=[],p=!1;function u(...c){return s.push(this),o.push(++pe),(p?n:l.shift()||n||r.getOriginal()||(()=>{})).apply(this,c)}let i=t.name;t.getMockName=()=>i||"vi.fn()",t.mockName=c=>(i=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,y){let h=n;n=c,r.willCall(u),p=!0;let R=()=>{n=h,p=!1},O=y();return O instanceof Promise?O.then(()=>(R(),t)):(R(),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),ce.add(t),t}var P=e=>ue(D({spy:e||(()=>{})},"spy"));beforeEach(()=>{global.window.fetch=P()});afterEach(()=>{global.window.fetch.mockReset()});var le=async()=>{let e={json:()=>Promise.resolve(),status:200,ok:!0,headers:new Headers({"Content-Type":"application/json"})};return Promise.resolve(e)},F=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)},me=e=>console.warn(`
1
+ import*as _ from"react";import k from"chalk";import j 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 Ne(e){W={...W,...e}}var d=()=>({...W});var N=e=>t=>{let{method:s="GET",path:n,host:o=d().defaultHost,requestBody:r=void 0,catchParams:a}=t,l=o+n,i=!d().handleQueryParams||a,u=j({url:i?l:l.split("?")[0],method:s.toUpperCase(),requestBody:r}),p;return"_bodyInit"in e&&e._bodyInit!==void 0&&(p=JSON.parse(e._bodyInit)),j({url:i?e.url:e.url.split("?")[0],method:e.method,requestBody:p})===u};function T(e,t){if(!e)throw new Error(t)}function w(e,t){return typeof t===e}function ie(e){return e instanceof Promise}function A(e,t,s){Object.defineProperty(e,t,s)}function b(e,t,s){Object.defineProperty(e,t,{value:s})}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=>(A(e,M,{value:{reset:()=>pe(e[M])}}),e[M]),E=e=>e[M]||ue(e);function le(e){T(w("function",e)||w("undefined",e),"cannot spy on a non-function value");let t=function(...n){let o=E(t);o.called=!0,o.callCount++,o.calls.push(n);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,n,new.target):a=o.impl.apply(this,n),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};b(t,"_isMockFunction",!0),b(t,"length",e?e.length:0),b(t,"name",e&&e.name||"spy");let s=E(t);return s.reset(),s.impl=e,t}var S=(e,t)=>Object.getOwnPropertyDescriptor(e,t),$=(e,t)=>{t!=null&&typeof t=="function"&&t.prototype!=null&&Object.setPrototypeOf(e.prototype,t.prototype)};function D(e,t,s){T(!w("undefined",e),"spyOn could not find an object to spy upon"),T(w("object",e)||w("function",e),"cannot spyOn on a primitive value");let[n,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=S(e,n),a=Object.getPrototypeOf(e),l=a&&S(a,n),i=r||l;T(i||n in e,`${String(n)} does not exist`);let u=!1;o==="value"&&i&&!i.value&&i.get&&(o="get",u=!0,s=i.get());let p;i?p=i[o]:o!=="value"?p=()=>e[n]:p=e[n],s||(s=p);let m=le(s);o==="value"&&$(m,p);let c=R=>{let{value:I,...v}=i||{configurable:!0,writable:!0};o!=="value"&&delete v.writable,v[o]=R,A(e,n,v)},y=()=>i?A(e,n,i):c(p),h=m[M];return b(h,"restore",y),b(h,"getOriginal",()=>u?p():p),b(h,"willCall",R=>(h.impl=R,m)),c(u?()=>($(m,s),m):m),ce.add(m),m}var de=new Set,he=0;function fe(e){let t=e,s,n=[],o=[],r=E(e),a={get calls(){return r.calls},get instances(){return n},get invocationCallOrder(){return o},get results(){return r.results.map(([c,y])=>({type:c==="error"?"throw":"return",value:y}))},get lastCall(){return r.calls[r.calls.length-1]}},l=[],i=!1;function u(...c){return n.push(this),o.push(++he),(i?s:l.shift()||s||r.getOriginal()||(()=>{})).apply(this,c)}let p=t.name;t.getMockName=()=>p||"vi.fn()",t.mockName=c=>(p=c,t),t.mockClear=()=>(r.reset(),n=[],o=[],t),t.mockReset=()=>(t.mockClear(),s=()=>{},l=[],t),t.mockRestore=()=>(t.mockReset(),r.restore(),s=void 0,t),t.getMockImplementation=()=>s,t.mockImplementation=c=>(s=c,r.willCall(u),t),t.mockImplementationOnce=c=>(l.push(c),t);function m(c,y){let h=s;s=c,r.willCall(u),i=!0;let R=()=>{s=h,i=!1},I=y();return I instanceof Promise?I.then(()=>(R(),t)):(R(),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 P=e=>fe(D({spy:e||(()=>{})},"spy"));beforeEach(()=>{global.window.fetch=P()});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)},U=async e=>{let{responseBody:t,status:s=200,headers:n={},delay:o}=e,r={json:()=>Promise.resolve(t),status:s,ok:s>=200&&s<=299,headers:new Headers({"Content-Type":"application/json",...n})};return o?new Promise(a=>setTimeout(()=>a(r),o)):Promise.resolve(r)},ye=e=>console.warn(`
2
2
  ${k.white.bold.bgRed("wrapito")} ${k.redBright.bold("cannot find any mock matching:")}
3
3
  ${k.greenBright(`URL: ${e.url}`)}
4
4
  ${k.greenBright(`METHOD: ${e.method?.toLowerCase()}`)}
5
5
  ${k.greenBright(`REQUEST BODY: ${e._bodyInit}`)}
6
- `),U=async(e,t,n)=>{let s=e.find(S(t));if(!s)return n&&me(t),le();let{multipleResponses:o}=s;if(!o)return F(s);let r=o.find(a=>!a.hasBeenReturned);if(!r){n&&de(s);return}return r.hasBeenReturned=!0,F(r)},L=(e=[],t=!1)=>{global.window.fetch.mockImplementation((s,o)=>{if(typeof s=="string"){let a=new Request(s,o);return U(e,a,t)}return U(e,s,t)})},de=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,n=k.greenBright(t);console.warn(n)};var C,f=e=>{C={...C,...e}},g=()=>({...C});beforeEach(()=>{global.fetch=P()});afterEach(()=>{global.fetch.mockReset()});var Je=e=>(f({Component:e,responses:[],props:{},path:"",hasPath:!1,debug:process.env.npm_config_debugRequests==="true"}),x()),x=()=>{let e=ye();return{withProps:Re,withNetwork:we,atPath:be,debugRequests:ke,mount:xe,...e}},he=e=>{let t=g(),n=[...t.responses,...e];f({...t,responses:n})},fe=(e,t)=>(t({addResponses:he},e),x()),ge=(e,t)=>{let{extend:n}=d(),s=n[t];return{...e,[t]:(...o)=>fe(o,s)}},ye=()=>{let{extend:e}=d();return Object.keys(e).reduce(ge,{})},Re=e=>{let t=g();return f({...t,props:e}),x()},we=(e=[])=>{let t=g(),n=Array.isArray(e)?e:[e];return f({...t,responses:[...t.responses,...n]}),x()},be=(e,t)=>{let n=g();return f({...n,historyState:t,path:e,hasPath:!0}),x()},ke=()=>{let e=g();return f({...e,debug:!0}),x()},xe=()=>{let{portal:e,changeRoute:t,history:n,mount:s}=d(),{Component:o,props:r,responses:a,path:l,hasPath:p,debug:u,historyState:i}=g(),m=o;return e&&Te(e),p&&n&&(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"),n.push(l,i)),p&&!n&&t(l),L(a,u),s(_.createElement(m,{...r}))},Te=e=>{if(document.getElementById(e))return;let t=document.createElement("div");t.setAttribute("id",e),document.body.appendChild(t)};import{diff as Ee}from"jest-diff";var A=(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}},G=(e,t,n)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${n} times, you expected ${t} times`}),V=(e,t)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch method does not match, expected ${e} received ${t??"none"}`}),Q=(e,t)=>{let n=t.map(s=>Ee(e,s)).join(`
6
+ `),F=async(e,t,s)=>{let n=e.find(N(t));if(!n)return s&&ye(t),ge();let{multipleResponses:o}=n;if(!o)return U(n);let r=o.find(a=>!a.hasBeenReturned);if(!r){s&&Re(n);return}return r.hasBeenReturned=!0,U(r)},L=(e=[],t=!1)=>{global.window.fetch.mockImplementation((n,o)=>{if(typeof n=="string"){let a=new Request(n,o);return F(e,a,t)}return F(e,n,t)})},Re=e=>{let t=`\u{1F32F} Wrapito: Missing response in the multipleResponses array for path ${e.path} and method ${e.method}.`,s=k.greenBright(t);console.warn(s)};var C,f=e=>{C={...C,...e}},g=()=>({...C});beforeEach(()=>{global.fetch=P()});afterEach(()=>{global.fetch.mockReset()});var Xe=e=>(f({Component:e,responses:[],props:{},path:"",hasPath:!1,debug:process.env.npm_config_debugRequests==="true"}),x()),x=()=>{let e=xe();return{withProps:Me,withNetwork:Te,atPath:Ee,debugRequests:Pe,mount:Oe,...e}},we=e=>{let t=g(),s=[...t.responses,...e];f({...t,responses:s})},be=(e,t)=>(t({addResponses:we},e),x()),ke=(e,t)=>{let{extend:s}=d(),n=s[t];return{...e,[t]:(...o)=>be(o,n)}},xe=()=>{let{extend:e}=d();return Object.keys(e).reduce(ke,{})},Me=e=>{let t=g();return f({...t,props:e}),x()},Te=(e=[])=>{let t=g(),s=Array.isArray(e)?e:[e];return f({...t,responses:[...t.responses,...s]}),x()},Ee=(e,t)=>{let s=g();return f({...s,historyState:t,path:e,hasPath:!0}),x()},Pe=()=>{let e=g();return f({...e,debug:!0}),x()},Oe=()=>{let{portal:e,portals:t,changeRoute:s,history:n,mount:o}=d(),{Component:r,props:a,responses:l,path:i,hasPath:u,debug:p,historyState:m}=g(),c=r;return e&&G(e),t&&qe(t),u&&n&&(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"),n.push(i,m)),u&&!n&&s(i),L(l,p),o(_.createElement(c,{...a}))},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)},qe=e=>{e.forEach(t=>{G(t)})};import{diff as Ie}from"jest-diff";var H=(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}},V=(e,t,s)=>({pass:!1,message:()=>`\u{1F32F} Wrapito: ${e} is called ${s} 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 s=t.map(n=>Ie(e,n)).join(`
7
7
 
8
8
  `);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Fetch body does not match.
9
- ${n}`}},J=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),B=()=>({pass:!0,message:()=>"Test passing"}),Y=(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 Me from"deep-equal";var Pe=()=>{let e=d().defaultHost;return e?.includes("http")?e:"https://default.com"},Ie=(e="",t,n)=>t.includes(n)?t:e+t,j=e=>e instanceof Request,Oe=e=>j(e)?e.url:e,I=(e,t={method:"GET"})=>fetch.mock.calls.filter(([s])=>{let o=Oe(s),r=Pe(),a=new URL(o,r),l=Ie(t?.host,e,r),p=t?.host||r,u=new URL(l,p),i=a.pathname===u.pathname,m=a.search===u.search,c=a.host===u.host;return u.search?i&&m:t?.host?i&&c:i}),z=e=>e.flat(1).filter(j).map(t=>t.method),K=e=>e.flat(1).filter(j).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),X=(e,t)=>e&&!t.includes(e),Z=(e,t)=>t.map(s=>Me(e,s)).every(s=>s===!1),ee=e=>e.length===0;var We=(e,t)=>{let n=I(e);if(ee(n))return A(e);let s=z(n),o=t?.method;if(X(o,s))return V(o,s);let r=K(n),a=t?.body;return a?Z(a,r)?Q(a,r):B():J()},qe=(e,t={method:"GET"})=>I(e,t).length?Y(e,t):A(e,t),ve=(e,t,n={method:"GET"})=>{let s=I(e,n);return s.length!==t?G(e,t,s.length):B()},st={toHaveBeenFetched:qe,toHaveBeenFetchedWith:We,toHaveBeenFetchedTimes:ve};export{st as assertions,Ae as configure,d as getConfig,st as matchers,Je as wrap};
9
+ ${s}`}},Y=(e,t)=>{let s=t.find(n=>e!==n);return{pass:!1,message:()=>`\u{1F32F} Wrapito: Host request does not match, expected ${e} received ${s}`}},z=()=>({pass:!1,message:()=>"\u{1F32F} Wrapito: Unable to find body."}),B=()=>({pass:!0,message:()=>"Test passing"}),K=(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 ve from"deep-equal";var X=()=>{let e=d().defaultHost;return e?.includes("http")?e:"https://default.com"},We=(e="",t,s)=>t.includes(s)?t:e+t,O=e=>e instanceof Request,Ae=e=>O(e)?e.url:e,q=(e,t={method:"GET"})=>fetch.mock.calls.filter(([n])=>{let o=Ae(n),r=X(),a=new URL(o,r),l=We(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(O).map(t=>t.method),ee=e=>e.flat(1).filter(O).map(t=>t._bodyInit?JSON.parse(t._bodyInit):{}),te=e=>e.flat(1).filter(O).map(t=>new URL(t.url,X()).hostname),se=(e,t)=>e&&!t.includes(e),ne=(e,t)=>t.map(n=>ve(e,n)).every(n=>n===!1),oe=(e,t)=>t.every(n=>n!==e),re=e=>e.length===0;var Ce=(e,t)=>{let s=q(e);if(re(s))return H(e);let n=Z(s),o=t?.method;if(se(o,n))return Q(o,n);let r=ee(s),a=t?.body;if(!a)return z();if(ne(a,r))return J(a,r);let l=te(s),i=t?.host;return i&&oe(i,l)?Y(i,l):B()},He=(e,t={method:"GET"})=>q(e,t).length?K(e,t):H(e,t),Be=(e,t,s={method:"GET"})=>{let n=q(e,s);return n.length!==t?V(e,t,n.length):B()},it={toHaveBeenFetched:He,toHaveBeenFetchedWith:Ce,toHaveBeenFetchedTimes:Be};export{it as assertions,Ne as configure,d as getConfig,it as matchers,Xe as wrap};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrapito",
3
- "version": "13.0.0-beta2",
3
+ "version": "13.0.0",
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,7 +52,7 @@
52
52
  },
53
53
  "homepage": "https://github.com/mercadona/wrapito#readme",
54
54
  "dependencies": {
55
- "chalk": "^4.1.2",
55
+ "chalk": "^5.6.2",
56
56
  "deep-equal": "^2.2.3",
57
57
  "jest-diff": "^29.7.0",
58
58
  "object-hash": "^3.0.0",