@gem-sdk/system 1.58.0-dev.143 → 1.58.0-dev.145

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.
Files changed (32) hide show
  1. package/dist/cjs/component/template.js +89 -0
  2. package/dist/cjs/index.js +6 -0
  3. package/dist/esm/component/template.js +83 -0
  4. package/dist/esm/index.js +1 -0
  5. package/dist/types/index.d.ts +8 -1
  6. package/package.json +15 -6
  7. package/src/component/__tests__/ template.test.tsx +0 -76
  8. package/src/component/__tests__/createAttr.test.ts +0 -62
  9. package/src/component/__tests__/createClass.test.ts +0 -68
  10. package/src/component/__tests__/createContent.test.ts +0 -52
  11. package/src/component/__tests__/createStateOrContext.test.ts +0 -129
  12. package/src/component/__tests__/createStyle.test.ts +0 -63
  13. package/src/component/createAttr.ts +0 -44
  14. package/src/component/createClass.ts +0 -48
  15. package/src/component/createContent.ts +0 -20
  16. package/src/component/createStateOrContext.ts +0 -70
  17. package/src/component/createStyle.ts +0 -53
  18. package/src/component/template.ts +0 -119
  19. package/src/component/types.ts +0 -9
  20. package/src/component/utils/__tests__/toCamelCaseKeys.test.ts +0 -79
  21. package/src/component/utils/toCamelCaseKeys.ts +0 -20
  22. package/src/e2e-tests/README.md +0 -1
  23. package/src/examples/components/text/DemoText.liquid.ts +0 -49
  24. package/src/examples/components/text/DemoText.tsx +0 -50
  25. package/src/examples/components/text/common/__tests__/globalTypoClasses.test.ts +0 -11
  26. package/src/examples/components/text/common/getAttr.ts +0 -7
  27. package/src/examples/components/text/common/getStyle.ts +0 -5
  28. package/src/examples/components/text/common/globalTypoClasses.ts +0 -5
  29. package/src/examples/components/text/e2e-tests/DemoText.spec.tsx +0 -23
  30. package/src/examples/components/text/e2e-tests/DemoText.tsx +0 -23
  31. package/src/index.ts +0 -34
  32. package/src/validator/README.md +0 -1
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ /*
4
+
5
+ Liquid in liquid.ts
6
+ <div>
7
+ Liquid(`
8
+ {%-if productSelectedVariant == empty or productSelectedVariant == null -%}
9
+ {%- assign productSelectedVariant = product.selected_or_first_available_variant -%}
10
+ {%- endif -%}
11
+ {%-if variant == empty or variant == null -%}
12
+ {%- assign variant = product.selected_or_first_available_variant -%}
13
+ {%- endif -%}
14
+ `)
15
+ </div>
16
+
17
+ IF in tsx & liquid.ts
18
+ <div {...attrs}>
19
+ {
20
+ If(product.id != "", (
21
+ <label className={classes} style={styles}>
22
+ {content}
23
+ </label>
24
+ ), (
25
+ <label className={classes} style={styles}>
26
+ {content}
27
+ </label>
28
+ ))
29
+ }
30
+ </div>
31
+
32
+ LiquidIF in liquid.ts
33
+ <div {...attrs}>
34
+ {
35
+ LiquidIf("product.quanity > 0", `
36
+ <label className={classes} style={styles}>
37
+ {content}
38
+ </label>
39
+ `, `
40
+ <label className={classes} style={styles}>
41
+ {content}
42
+ </label>
43
+ `)
44
+ }
45
+ </div>
46
+
47
+ For in tsx & liquid.ts
48
+ {
49
+ For(numbers, (item, index) => (
50
+ <div key={index}>
51
+ {index + 1}: Số {item}
52
+ </div>
53
+ ))
54
+ }
55
+
56
+ LiquidFor in tsx & liquid.ts
57
+ {
58
+ LiquidFor('(item, index) in items', `
59
+ <div key="{{ forloop.index }}">
60
+ {{ forloop.index + 1}}: Số {{item}}
61
+ </div>
62
+ `)
63
+ }
64
+
65
+ */ const Liquid = (code)=>{
66
+ return code;
67
+ };
68
+ const For = (items, renderFn)=>{
69
+ return items.map((item, index)=>renderFn(item, index));
70
+ };
71
+ const LiquidFor = (c, t)=>{
72
+ return `{% for ${c} %}${typeof t === 'string' ? t : t()}{% endfor %}`;
73
+ };
74
+ const If = (condition, trueResult, falseResult)=>{
75
+ if (condition) {
76
+ // Trả về kết quả đúng nếu điều kiện là true
77
+ return typeof trueResult === 'function' ? trueResult() : trueResult;
78
+ } else {
79
+ // Trả về kết quả sai nếu điều kiện là false
80
+ return falseResult ? typeof falseResult === 'function' ? falseResult() : falseResult : null; // Nếu không có falseResult, trả về null
81
+ }
82
+ };
83
+ const LiquidIf = (c, t, f)=>`{% if ${c} %}${typeof t === 'string' ? t : t()}${f ? `{% else %}${typeof f === 'string' ? f : f?.()}` : ''}{% endif %}`;
84
+
85
+ exports.For = For;
86
+ exports.If = If;
87
+ exports.Liquid = Liquid;
88
+ exports.LiquidFor = LiquidFor;
89
+ exports.LiquidIf = LiquidIf;
package/dist/cjs/index.js CHANGED
@@ -5,6 +5,7 @@ var createStyle = require('./component/createStyle.js');
5
5
  var createContent = require('./component/createContent.js');
6
6
  var createClass = require('./component/createClass.js');
7
7
  var createStateOrContext = require('./component/createStateOrContext.js');
8
+ var template = require('./component/template.js');
8
9
 
9
10
  const createAttrReact = createAttr.createAttr;
10
11
  const createContentReact = createContent.createContent;
@@ -16,6 +17,11 @@ exports.createStyleReact = createStyle.createStyleReact;
16
17
  exports.createContent = createContent.createContent;
17
18
  exports.createClass = createClass.createClass;
18
19
  exports.createStateOrContext = createStateOrContext.createStateOrContext;
20
+ exports.For = template.For;
21
+ exports.If = template.If;
22
+ exports.Liquid = template.Liquid;
23
+ exports.LiquidFor = template.LiquidFor;
24
+ exports.LiquidIf = template.LiquidIf;
19
25
  exports.createAttrReact = createAttrReact;
20
26
  exports.createClassReact = createClassReact;
21
27
  exports.createContentReact = createContentReact;
@@ -0,0 +1,83 @@
1
+ /*
2
+
3
+ Liquid in liquid.ts
4
+ <div>
5
+ Liquid(`
6
+ {%-if productSelectedVariant == empty or productSelectedVariant == null -%}
7
+ {%- assign productSelectedVariant = product.selected_or_first_available_variant -%}
8
+ {%- endif -%}
9
+ {%-if variant == empty or variant == null -%}
10
+ {%- assign variant = product.selected_or_first_available_variant -%}
11
+ {%- endif -%}
12
+ `)
13
+ </div>
14
+
15
+ IF in tsx & liquid.ts
16
+ <div {...attrs}>
17
+ {
18
+ If(product.id != "", (
19
+ <label className={classes} style={styles}>
20
+ {content}
21
+ </label>
22
+ ), (
23
+ <label className={classes} style={styles}>
24
+ {content}
25
+ </label>
26
+ ))
27
+ }
28
+ </div>
29
+
30
+ LiquidIF in liquid.ts
31
+ <div {...attrs}>
32
+ {
33
+ LiquidIf("product.quanity > 0", `
34
+ <label className={classes} style={styles}>
35
+ {content}
36
+ </label>
37
+ `, `
38
+ <label className={classes} style={styles}>
39
+ {content}
40
+ </label>
41
+ `)
42
+ }
43
+ </div>
44
+
45
+ For in tsx & liquid.ts
46
+ {
47
+ For(numbers, (item, index) => (
48
+ <div key={index}>
49
+ {index + 1}: Số {item}
50
+ </div>
51
+ ))
52
+ }
53
+
54
+ LiquidFor in tsx & liquid.ts
55
+ {
56
+ LiquidFor('(item, index) in items', `
57
+ <div key="{{ forloop.index }}">
58
+ {{ forloop.index + 1}}: Số {{item}}
59
+ </div>
60
+ `)
61
+ }
62
+
63
+ */ const Liquid = (code)=>{
64
+ return code;
65
+ };
66
+ const For = (items, renderFn)=>{
67
+ return items.map((item, index)=>renderFn(item, index));
68
+ };
69
+ const LiquidFor = (c, t)=>{
70
+ return `{% for ${c} %}${typeof t === 'string' ? t : t()}{% endfor %}`;
71
+ };
72
+ const If = (condition, trueResult, falseResult)=>{
73
+ if (condition) {
74
+ // Trả về kết quả đúng nếu điều kiện là true
75
+ return typeof trueResult === 'function' ? trueResult() : trueResult;
76
+ } else {
77
+ // Trả về kết quả sai nếu điều kiện là false
78
+ return falseResult ? typeof falseResult === 'function' ? falseResult() : falseResult : null; // Nếu không có falseResult, trả về null
79
+ }
80
+ };
81
+ const LiquidIf = (c, t, f)=>`{% if ${c} %}${typeof t === 'string' ? t : t()}${f ? `{% else %}${typeof f === 'string' ? f : f?.()}` : ''}{% endif %}`;
82
+
83
+ export { For, If, Liquid, LiquidFor, LiquidIf };
package/dist/esm/index.js CHANGED
@@ -3,6 +3,7 @@ export { createStyle, createStyleReact } from './component/createStyle.js';
3
3
  import { createContent } from './component/createContent.js';
4
4
  import { createClass } from './component/createClass.js';
5
5
  export { createStateOrContext } from './component/createStateOrContext.js';
6
+ export { For, If, Liquid, LiquidFor, LiquidIf } from './component/template.js';
6
7
 
7
8
  const createAttrReact = createAttr;
8
9
  const createContentReact = createContent;
@@ -27,6 +27,13 @@ declare const createStateOrContext: (obj: {
27
27
  [key: string]: any;
28
28
  };
29
29
 
30
+ type CallbackCondition = () => JSX.Element | string;
31
+ declare const Liquid: (code: string) => string;
32
+ declare const For: <T>(items: T[], renderFn: (item: T, index: number) => JSX.Element) => JSX.Element[];
33
+ declare const LiquidFor: (c: string, t: string | CallbackCondition) => string;
34
+ declare const If: (condition: boolean | null | undefined, trueResult: string | JSX.Element | CallbackCondition, falseResult?: string | JSX.Element | CallbackCondition) => JSX.Element | string | null;
35
+ declare const LiquidIf: (c: string, t: string | CallbackCondition, f?: string | CallbackCondition) => string;
36
+
30
37
  declare const createAttrReact: (obj: {
31
38
  [key: string]: string | number;
32
39
  }) => {
@@ -39,4 +46,4 @@ declare const createClassReact: (obj: {
39
46
  [key: string]: boolean | undefined;
40
47
  }) => string;
41
48
 
42
- export { createAttr, createAttrReact, createClass, createClassReact, createContent, createContentReact, createStateOrContext, createStyle, createStyleReact };
49
+ export { For, If, Liquid, LiquidFor, LiquidIf, createAttr, createAttrReact, createClass, createClassReact, createContent, createContentReact, createStateOrContext, createStyle, createStyleReact };
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@gem-sdk/system",
3
- "version": "1.58.0-dev.143",
3
+ "version": "1.58.0-dev.145",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
- "main": "src/index.ts",
6
+ "main": "dist/cjs/index.js",
7
7
  "files": [
8
- "dist",
9
- "src"
8
+ "dist"
10
9
  ],
11
10
  "scripts": {
12
11
  "cleanup": "rimraf es dist lib",
@@ -21,7 +20,17 @@
21
20
  "type-check": "yarn tsc --noEmit"
22
21
  },
23
22
  "dependencies": {
24
- "@gem-sdk/core": "1.58.0-dev.135"
23
+ "@gem-sdk/core": "1.58.0-dev.145"
25
24
  },
26
- "devDependencies": {}
25
+ "devDependencies": {},
26
+ "module": "dist/esm/index.js",
27
+ "types": "dist/types/index.d.ts",
28
+ "exports": {
29
+ "./package.json": "./package.json",
30
+ ".": {
31
+ "import": "./dist/esm/index.js",
32
+ "require": "./dist/cjs/index.js",
33
+ "types": "./dist/types/index.d.ts"
34
+ }
35
+ }
27
36
  }
@@ -1,76 +0,0 @@
1
- import { describe, test, expect, jest } from '@jest/globals';
2
- import { For, If, Liquid, LiquidFor, LiquidIf, Unless, LiquidUnless } from '../template';
3
-
4
- // Mock callback
5
- const mockCallback = jest.fn(() => '<div>Mock Element</div>');
6
-
7
- describe('Testing utility functions', () => {
8
- test('Liquid should return the input string', () => {
9
- const input = "Hello, World!";
10
- const result = Liquid(input);
11
- expect(result).toBe(input);
12
- });
13
-
14
- test('For should render a list of JSX elements', () => {
15
- const items = [1, 2, 3];
16
- const renderFn = (item: number) => <div key={item}>Item {item}</div>;
17
- const result = For(items, renderFn);
18
- expect(result).toHaveLength(3);
19
- expect(result[0]).toEqual(<div key={items[0]}>Item {items[0]}</div>);
20
- });
21
-
22
- test('LiquidFor should render a Liquid template', () => {
23
- const code = "item in items";
24
- const template = "Content";
25
- const result = LiquidFor(code, template);
26
- expect(result).toBe(`{% for ${code} %}${template}{% endfor %}`);
27
- });
28
-
29
- test('If should return trueResult when condition is true', () => {
30
- const result = If(true, "Yes", "No");
31
- expect(result).toBe("Yes");
32
- });
33
-
34
- test('If should return falseResult when condition is false', () => {
35
- const result = If(false, "Yes", "No");
36
- expect(result).toBe("No");
37
- });
38
-
39
- test('If should handle JSX.Element', () => {
40
- const result = If(true, <div>True</div>, <div>False</div>);
41
- expect(result).toEqual(<div>True</div>);
42
- });
43
-
44
- test('LiquidIf should render a correct Liquid if-else template', () => {
45
- const condition = "x > 10";
46
- const trueResult = "Greater";
47
- const falseResult = "Smaller";
48
- const result = LiquidIf(condition, trueResult, falseResult);
49
- expect(result).toBe(`{% if ${condition} %}${trueResult}{% else %}${falseResult}{% endif %}`);
50
- });
51
-
52
- test('Unless should reverse the condition', () => {
53
- const result = Unless(false, "True", "False");
54
- expect(result).toBe("True");
55
- });
56
-
57
- test('LiquidUnless should render a correct Liquid unless-else template', () => {
58
- const condition = "x > 10";
59
- const trueResult = "Greater";
60
- const falseResult = "Smaller";
61
- const result = LiquidUnless(condition, trueResult, falseResult);
62
- expect(result).toBe(`{% unless ${condition} %}${trueResult}{% else %}${falseResult}{% endunless %}`);
63
- });
64
-
65
- test('If should handle callback conditions', () => {
66
- const trueResult = mockCallback;
67
- If(true, trueResult);
68
- expect(mockCallback).toHaveBeenCalledTimes(1);
69
- });
70
-
71
- test('LiquidIf should handle callback conditions', () => {
72
- const condition = "x > 10";
73
- LiquidIf(condition, mockCallback);
74
- expect(mockCallback).toHaveBeenCalledTimes(2); // Call count should include other tests
75
- });
76
- });
@@ -1,62 +0,0 @@
1
- import { describe, test, expect, beforeEach, jest } from '@jest/globals';
2
- import { createAttr } from '../createAttr';
3
-
4
- // Mock console.error to capture error messages
5
- global.console.error = jest.fn();
6
-
7
- describe('createAttr', () => {
8
- beforeEach(() => {
9
- // Clear the console.error mock before each test
10
- (console.error as jest.Mock).mockClear();
11
- });
12
-
13
- test('should log error for key without "data-gp-" prefix', () => {
14
- createAttr({ invalidKey: 'some value' });
15
- expect(console.error).toHaveBeenCalledWith(
16
- 'Invalid attribute key: "invalidKey". Must start with "data-gp-".',
17
- );
18
- });
19
-
20
- test('should log error for key with uppercase letters', () => {
21
- createAttr({ 'data-gp-UppercaseKey': 'some value' });
22
- expect(console.error).toHaveBeenCalledWith(
23
- 'Invalid attribute key: "data-gp-UppercaseKey". Must not contain uppercase letters.',
24
- );
25
- });
26
-
27
- test('should log error for nested object', () => {
28
- createAttr({ 'data-gp-nested': { fontSize: '12px' } } as any);
29
- expect(console.error).toHaveBeenCalledWith(
30
- 'Invalid nested attribute for key "data-gp-nested". Nested objects are not supported.',
31
- );
32
- });
33
-
34
- test('should log error for invalid value type', () => {
35
- createAttr({ 'data-gp-invalidType': true as any });
36
- expect(console.error).toHaveBeenCalledWith(
37
- 'Invalid attribute value for key "data-gp-invalidType": true. Must be a string or number.',
38
- );
39
- });
40
-
41
- test('should handle multiple errors in one call', () => {
42
- createAttr({
43
- invalidKey: 'some value', // Invalid prefix
44
- 'data-gp-UppercaseKey': 'some value', // Uppercase in key
45
- 'data-gp-nested': { fontSize: '12px' }, // Nested object
46
- 'data-gp-invalidType': true as any, // Invalid value type
47
- } as any);
48
-
49
- expect(console.error).toHaveBeenCalledWith(
50
- 'Invalid attribute key: "invalidKey". Must start with "data-gp-".',
51
- );
52
- expect(console.error).toHaveBeenCalledWith(
53
- 'Invalid attribute key: "data-gp-UppercaseKey". Must not contain uppercase letters.',
54
- );
55
- expect(console.error).toHaveBeenCalledWith(
56
- 'Invalid nested attribute for key "data-gp-nested". Nested objects are not supported.',
57
- );
58
- expect(console.error).toHaveBeenCalledWith(
59
- 'Invalid attribute value for key "data-gp-invalidType": true. Must be a string or number.',
60
- );
61
- });
62
- });
@@ -1,68 +0,0 @@
1
- import { describe, test, expect, beforeAll, afterEach, jest } from '@jest/globals';
2
-
3
- // Import the function
4
- import { createClass } from '../createClass';
5
-
6
- // Declare console.error as a Jest mock
7
- beforeAll(() => {
8
- global.console.error = jest.fn();
9
- });
10
-
11
- afterEach(() => {
12
- // Clear the console.error mock after each test
13
- (console.error as jest.Mock).mockClear();
14
- });
15
-
16
- describe('createClass', () => {
17
- test('should return empty string and log error for invalid input', () => {
18
- expect(createClass(null as any)).toBe('');
19
- expect(console.error).toHaveBeenCalledWith('Expected an object as input.');
20
-
21
- expect(createClass(123 as any)).toBe('');
22
- expect(console.error).toHaveBeenCalledWith('Expected an object as input.');
23
- });
24
-
25
- test('should log an error for class names exceeding 30 characters', () => {
26
- createClass({ averyverylongclassnameexceeding30characters: true });
27
- expect(console.error).toHaveBeenCalledWith(
28
- 'Class name "averyverylongclassnameexceeding30characters" exceeds the maximum length of 30 characters.',
29
- );
30
- });
31
-
32
- test('should log an error for class names with spaces', () => {
33
- createClass({ 'class with space': true });
34
- expect(console.error).toHaveBeenCalledWith(
35
- 'Class name "class with space" should not contain spaces.',
36
- );
37
- });
38
-
39
- test('should log an error for class names with uppercase letters', () => {
40
- createClass({ ClassWithUpperCase: true });
41
- expect(console.error).toHaveBeenCalledWith(
42
- 'Class name "ClassWithUpperCase" should be in lowercase.',
43
- );
44
- });
45
-
46
- test('should not log any errors for valid class names', () => {
47
- createClass({ validclassname: true, anotherclass: true });
48
- expect(console.error).not.toHaveBeenCalled();
49
- });
50
-
51
- test('should handle multiple errors in one call', () => {
52
- createClass({
53
- ValidClassWithUpper: true,
54
- 'class with space': true,
55
- averyverylongclassnameexceeding30characters: true,
56
- });
57
-
58
- expect(console.error).toHaveBeenCalledWith(
59
- 'Class name "ValidClassWithUpper" should be in lowercase.',
60
- );
61
- expect(console.error).toHaveBeenCalledWith(
62
- 'Class name "class with space" should not contain spaces.',
63
- );
64
- expect(console.error).toHaveBeenCalledWith(
65
- 'Class name "averyverylongclassnameexceeding30characters" exceeds the maximum length of 30 characters.',
66
- );
67
- });
68
- });
@@ -1,52 +0,0 @@
1
- import { describe, test, expect, beforeEach, jest } from '@jest/globals';
2
-
3
- import { createContent } from '../createContent';
4
-
5
- // Mock console.error to capture error messages
6
- global.console.error = jest.fn();
7
-
8
- describe('createContent', () => {
9
- beforeEach(() => {
10
- // Clear the console.error mock before each test
11
- (console.error as jest.Mock).mockClear();
12
- });
13
-
14
- test('should return empty string and log error if content is not a string', () => {
15
- expect(createContent(12345 as any)).toBe('');
16
- expect(console.error).toHaveBeenCalledWith('Invalid content type: Content must be a string.');
17
-
18
- expect(createContent({} as any)).toBe('');
19
- expect(console.error).toHaveBeenCalledWith('Invalid content type: Content must be a string.');
20
- });
21
-
22
- test('should return empty string and log error for content with invalid {{}} pattern', () => {
23
- expect(createContent('{{Hello}} there')).toBe('');
24
- expect(console.error).toHaveBeenCalledWith(
25
- 'Invalid content format: "{{}}" placeholders must not contain only letters, e.g., "{{Hello}}".',
26
- );
27
-
28
- expect(createContent('Welcome {{World}}')).toBe('');
29
- expect(console.error).toHaveBeenCalledWith(
30
- 'Invalid content format: "{{}}" placeholders must not contain only letters, e.g., "{{Hello}}".',
31
- );
32
- });
33
-
34
- test('should return valid content without errors', () => {
35
- expect(createContent('This is valid content')).toBe('This is valid content');
36
- expect(console.error).not.toHaveBeenCalled();
37
-
38
- expect(createContent('Content with {{123}} is valid')).toBe('Content with {{123}} is valid');
39
- expect(console.error).not.toHaveBeenCalled();
40
-
41
- expect(createContent('Mix of {{valid1}} and {{valid2}}')).toBe(
42
- 'Mix of {{valid1}} and {{valid2}}',
43
- );
44
- expect(console.error).not.toHaveBeenCalled();
45
- });
46
-
47
- test('should pass with valid {{}} pattern containing more than just letters', () => {
48
- const content = '{{ product.title | t }}';
49
- expect(createContent(content)).toBe(content);
50
- expect(console.error).not.toHaveBeenCalled();
51
- });
52
- });
@@ -1,129 +0,0 @@
1
- import { describe, test, expect, beforeEach, jest } from '@jest/globals';
2
-
3
- import { createStateOrContext } from '../createStateOrContext';
4
-
5
- // Mock console.error to capture error messages
6
- global.console.error = jest.fn();
7
-
8
- describe('createStateOrContext', () => {
9
- beforeEach(() => {
10
- // Clear the console.error mock before each test
11
- (console.error as jest.Mock).mockClear();
12
- });
13
-
14
- test('should log error for key length exceeding 20 characters', () => {
15
- createStateOrContext({ thisKeyIsWayTooLongForOurRequirements: 'value' });
16
- expect(console.error).toHaveBeenCalledWith(
17
- 'Invalid key "thisKeyIsWayTooLongForOurRequirements": Key length must not exceed 20 characters.',
18
- );
19
- });
20
-
21
- test('should log error for key containing special characters', () => {
22
- createStateOrContext({ invalid_key: 'value' });
23
- expect(console.error).toHaveBeenCalledWith(
24
- 'Invalid key "invalid_key": Key must contain only alphabetic characters (no numbers or special characters).',
25
- );
26
- });
27
-
28
- test('should log error for key containing numbers', () => {
29
- createStateOrContext({ invalidKey1: 'value' });
30
- expect(console.error).toHaveBeenCalledWith(
31
- 'Invalid key "invalidKey1": Key must contain only alphabetic characters (no numbers or special characters).',
32
- );
33
- });
34
-
35
- test('should log error for key not in camelCase format', () => {
36
- createStateOrContext({ Invalidkey: 'value' });
37
- expect(console.error).toHaveBeenCalledWith(
38
- 'Invalid key "Invalidkey": Key must be in camelCase format.',
39
- );
40
- });
41
-
42
- test('should log error for nested object deeper than 3 levels', () => {
43
- createStateOrContext({
44
- levelOne: {
45
- levelTwo: {
46
- levelThree: {
47
- tooDeepKey: 'too deep',
48
- },
49
- },
50
- },
51
- });
52
- expect(console.error).toHaveBeenCalledWith(
53
- 'Invalid structure: Data must not be nested deeper than 3 levels.',
54
- );
55
- });
56
-
57
- test('should log error for invalid values (undefined, null, blank, false)', () => {
58
- createStateOrContext({
59
- validKey: 'value', // Valid
60
- undefinedKey: undefined, // Invalid
61
- nullKey: null, // Invalid
62
- emptyStringKey: '', // Invalid
63
- falseKey: false, // Invalid
64
- });
65
-
66
- expect(console.error).toHaveBeenCalledWith(
67
- 'Invalid value for key "undefinedKey": Value must not be undefined, null, blank, or false.',
68
- );
69
- expect(console.error).toHaveBeenCalledWith(
70
- 'Invalid value for key "nullKey": Value must not be undefined, null, blank, or false.',
71
- );
72
- expect(console.error).toHaveBeenCalledWith(
73
- 'Invalid value for key "emptyStringKey": Value must not be undefined, null, blank, or false.',
74
- );
75
- expect(console.error).toHaveBeenCalledWith(
76
- 'Invalid value for key "falseKey": Value must not be undefined, null, blank, or false.',
77
- );
78
- });
79
-
80
- test('should not log any errors for valid keys and values', () => {
81
- createStateOrContext({
82
- validKey: 'value',
83
- anotherValidKey: 123,
84
- nestedObject: {
85
- validNestedKey: 'nestedValue',
86
- anotherLevel: {
87
- validKey: 'value',
88
- },
89
- },
90
- });
91
- expect(console.error).not.toHaveBeenCalled();
92
- });
93
-
94
- test('should handle multiple errors in one call', () => {
95
- createStateOrContext({
96
- thisKeyIsWayTooLongForOurRequirements: 'value', // Key length
97
- invalid_key: 'value', // Special character
98
- invalidKey1: 'value', // Contains number
99
- InvalidCamelCase: 'value', // Not camelCase
100
- validKey: {
101
- nestedTooDeep: {
102
- anotherLevel: {
103
- tooDeepKey: 'too deep', // Exceeds depth
104
- },
105
- },
106
- },
107
- undefinedValue: undefined, // Invalid value
108
- });
109
-
110
- expect(console.error).toHaveBeenCalledWith(
111
- 'Invalid key "thisKeyIsWayTooLongForOurRequirements": Key length must not exceed 20 characters.',
112
- );
113
- expect(console.error).toHaveBeenCalledWith(
114
- 'Invalid key "invalid_key": Key must contain only alphabetic characters (no numbers or special characters).',
115
- );
116
- expect(console.error).toHaveBeenCalledWith(
117
- 'Invalid key "invalidKey1": Key must contain only alphabetic characters (no numbers or special characters).',
118
- );
119
- expect(console.error).toHaveBeenCalledWith(
120
- 'Invalid key "InvalidCamelCase": Key must be in camelCase format.',
121
- );
122
- expect(console.error).toHaveBeenCalledWith(
123
- 'Invalid structure: Data must not be nested deeper than 3 levels.',
124
- );
125
- expect(console.error).toHaveBeenCalledWith(
126
- 'Invalid value for key "undefinedValue": Value must not be undefined, null, blank, or false.',
127
- );
128
- });
129
- });