Skip to content

Commit 4e04f11

Browse files
authored
feat: support multiple carts (#46)
* feat: support multiple carts * chore: test on pr
1 parent 52c66b6 commit 4e04f11

File tree

6 files changed

+80
-16
lines changed

6 files changed

+80
-16
lines changed

.github/workflows/test.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Test
2+
on: [push, pull_request]
3+
jobs:
4+
test:
5+
name: Release
6+
runs-on: ubuntu-18.04
7+
steps:
8+
- name: Checkout
9+
uses: actions/checkout@v1
10+
- name: Setup Node.js
11+
uses: actions/setup-node@v1
12+
with:
13+
node-version: 12
14+
- name: Install dependencies
15+
run: npm install
16+
- name: Test package
17+
run: npm test

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ ReactDOM.render(
113113

114114
#### Props
115115

116-
- `id`: (_optional_) `id` for your cart to enable automatic cart retrieval via `window.localStorage`
116+
- `id`: (_optional_) `id` for your cart to enable automatic cart retrieval via `window.localStorage`. If you pass a `id` then you can use multiple instances of `CartProvider`.
117117
- `onSetItems`: Triggered only when `setItems` invoked
118118
- `onItemAdd`: Triggered on items added to your cart, unless the item already exists, then `onItemUpdate` will be invoked
119119
- `onItemUpdate`: Triggered on items updated in your cart, unless you are setting the quantity to `0`, then `onItemRemove` will be invoked

src/index.js renamed to index.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ export const initialState = {
1717
isEmpty: true,
1818
};
1919

20+
export const createCartIdentifier = (len = 12) =>
21+
[...Array(len)].map(() => (~~(Math.random() * 36)).toString(36)).join("");
22+
2023
export const useCart = () => useContext(CartContext);
2124

2225
function reducer(state, action) {
@@ -88,18 +91,18 @@ const calculateUniqueItems = (items = []) => items.length;
8891

8992
export function CartProvider({
9093
children,
91-
id = [...Array(12)]
92-
.map((i) => (~~(Math.random() * 36)).toString(36))
93-
.join(""),
94+
id: cartId,
9495
defaultItems = [],
9596
onSetItems,
9697
onItemAdd,
9798
onItemUpdate,
9899
onItemRemove,
99100
storage = useLocalStorage,
100101
}) {
102+
const id = cartId ? cartId : createCartIdentifier();
103+
101104
const [savedCart, saveCart] = storage(
102-
`react-use-cart`,
105+
id ? `react-use-cart-${id}` : `react-use-cart`,
103106
JSON.stringify({
104107
id,
105108
...initialState,

src/index.test.js renamed to index.test.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,55 @@
11
import React from "react";
22
import { renderHook, act } from "@testing-library/react-hooks";
33

4-
import { CartProvider, useCart, initialState } from "./";
4+
import { CartProvider, useCart, initialState, createCartIdentifier } from ".";
55

66
afterEach(() => window.localStorage.clear());
77

8+
describe("createCartIdentifier", () => {
9+
test("returns a 12 character string by default", () => {
10+
const id = createCartIdentifier();
11+
12+
expect(id).toHaveLength(12);
13+
});
14+
15+
test("returns a custom length string", () => {
16+
const id = createCartIdentifier(20);
17+
18+
expect(id).toHaveLength(20);
19+
});
20+
21+
test("created id is unique", () => {
22+
const id = createCartIdentifier();
23+
const id2 = createCartIdentifier();
24+
25+
expect(id).not.toEqual(id2);
26+
});
27+
});
28+
829
describe("CartProvider", () => {
30+
test("uses ID for cart if provided", () => {
31+
const wrapper = ({ children }) => (
32+
<CartProvider id="test">{children}</CartProvider>
33+
);
34+
35+
const { result } = renderHook(() => useCart(), {
36+
wrapper,
37+
});
38+
39+
expect(result.current.id).toEqual("test");
40+
});
41+
42+
test("creates an ID for cart if non provided", () => {
43+
const wrapper = ({ children }) => <CartProvider>{children}</CartProvider>;
44+
45+
const { result } = renderHook(() => useCart(), {
46+
wrapper,
47+
});
48+
49+
expect(result.current.id).toBeDefined();
50+
expect(result.current.id).toHaveLength(12);
51+
});
52+
953
test("initial cart meta state is set", () => {
1054
const wrapper = ({ children }) => (
1155
<CartProvider id="test">{children}</CartProvider>

rollup.config.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
import external from 'rollup-plugin-peer-deps-external'
2-
import resolve from 'rollup-plugin-node-resolve'
3-
import babel from 'rollup-plugin-babel'
4-
import commonjs from 'rollup-plugin-commonjs'
1+
import external from "rollup-plugin-peer-deps-external";
2+
import resolve from "rollup-plugin-node-resolve";
3+
import babel from "rollup-plugin-babel";
4+
import commonjs from "rollup-plugin-commonjs";
55

6-
import pkg from './package.json'
6+
import pkg from "./package.json";
77

88
export default {
9-
input: 'src/index.js',
9+
input: "index.js",
1010
output: [
1111
{
1212
file: pkg.main,
13-
format: 'cjs',
13+
format: "cjs",
1414
sourcemap: true,
1515
},
1616
{
1717
file: pkg.module,
18-
format: 'es',
18+
format: "es",
1919
sourcemap: true,
2020
},
2121
],
2222
plugins: [
2323
external(),
2424
resolve(),
2525
babel({
26-
exclude: 'node_modules/**',
26+
exclude: "node_modules/**",
2727
}),
2828
commonjs(),
2929
],
30-
}
30+
};
File renamed without changes.

0 commit comments

Comments
 (0)