@agents-inc/cli 0.60.1 → 0.64.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/CHANGELOG.md +48 -0
- package/README.md +23 -172
- package/dist/{chunk-G6WHCALR.js → chunk-3YNT3NX3.js} +13 -11
- package/dist/chunk-3YNT3NX3.js.map +1 -0
- package/dist/{chunk-WF6RM73R.js → chunk-4C7CSZC5.js} +27 -149
- package/dist/chunk-4C7CSZC5.js.map +1 -0
- package/dist/{chunk-EMIUPGPL.js → chunk-4KVBH2X4.js} +33 -14
- package/dist/chunk-4KVBH2X4.js.map +1 -0
- package/dist/{chunk-KIWFEBKH.js → chunk-52THXN5G.js} +14 -5
- package/dist/chunk-52THXN5G.js.map +1 -0
- package/dist/{chunk-TZXYBG3R.js → chunk-53URJ5XK.js} +448 -153
- package/dist/chunk-53URJ5XK.js.map +1 -0
- package/dist/{chunk-MKCHLXMY.js → chunk-6DEK3TDF.js} +10 -10
- package/dist/chunk-6DEK3TDF.js.map +1 -0
- package/dist/{chunk-SDKCQXWE.js → chunk-6IK2TCK7.js} +13 -6
- package/dist/chunk-6IK2TCK7.js.map +1 -0
- package/dist/chunk-6VIOO74O.js +51 -0
- package/dist/chunk-6VIOO74O.js.map +1 -0
- package/dist/{chunk-52XO4ULK.js → chunk-7DI3HGKL.js} +32 -14
- package/dist/chunk-7DI3HGKL.js.map +1 -0
- package/dist/{chunk-MGNYPVOJ.js → chunk-AQYAVLZK.js} +2 -2
- package/dist/{chunk-BNQ5O6LE.js → chunk-AUNBGZS4.js} +2 -2
- package/dist/chunk-BGPGQF35.js +248 -0
- package/dist/chunk-BGPGQF35.js.map +1 -0
- package/dist/chunk-BKL3DF2Q.js +45 -0
- package/dist/chunk-BKL3DF2Q.js.map +1 -0
- package/dist/{chunk-AX3SZZWA.js → chunk-BKTPEATV.js} +13 -6
- package/dist/chunk-BKTPEATV.js.map +1 -0
- package/dist/{chunk-H7WJK7NJ.js → chunk-CKPJTMNC.js} +13 -6
- package/dist/chunk-CKPJTMNC.js.map +1 -0
- package/dist/{chunk-MR6OBL3B.js → chunk-CXRVM7BA.js} +2 -4
- package/dist/chunk-CXRVM7BA.js.map +1 -0
- package/dist/{chunk-VR3CDXDT.js → chunk-EE5EPS32.js} +2 -2
- package/dist/{chunk-6OWHQ7HM.js → chunk-EGMQ3SXN.js} +2 -11
- package/dist/{chunk-6OWHQ7HM.js.map → chunk-EGMQ3SXN.js.map} +1 -1
- package/dist/{chunk-BMJZBLP7.js → chunk-EZ35IPXZ.js} +10 -7
- package/dist/chunk-EZ35IPXZ.js.map +1 -0
- package/dist/{chunk-OCEFD7V6.js → chunk-F3REOP7N.js} +3 -3
- package/dist/{chunk-C577AJE7.js → chunk-FGLUQSVU.js} +3 -3
- package/dist/{chunk-SEJF7CGJ.js → chunk-J4POGAJF.js} +24 -24
- package/dist/chunk-J4POGAJF.js.map +1 -0
- package/dist/{chunk-O6BA7Q2B.js → chunk-KFDTVSIC.js} +18 -8
- package/dist/chunk-KFDTVSIC.js.map +1 -0
- package/dist/{chunk-LWXRUR6B.js → chunk-LMZXL5RQ.js} +2 -2
- package/dist/{chunk-LWXRUR6B.js.map → chunk-LMZXL5RQ.js.map} +1 -1
- package/dist/{chunk-7FMEMXJ4.js → chunk-MOMI77PL.js} +100 -59
- package/dist/chunk-MOMI77PL.js.map +1 -0
- package/dist/{chunk-BFD5NZQ4.js → chunk-MVYJVKVT.js} +19 -11
- package/dist/chunk-MVYJVKVT.js.map +1 -0
- package/dist/{chunk-X5EG4EFP.js → chunk-MWGDG4QN.js} +2 -2
- package/dist/{chunk-TGLRDEEL.js → chunk-O2HK3NTG.js} +10 -6
- package/dist/chunk-O2HK3NTG.js.map +1 -0
- package/dist/{chunk-6G3KZSO4.js → chunk-OORWBS6F.js} +45 -52
- package/dist/chunk-OORWBS6F.js.map +1 -0
- package/dist/{chunk-CIG7IKX3.js → chunk-OV5UJWS5.js} +4 -4
- package/dist/{chunk-RO6LX3UV.js → chunk-R46CB36B.js} +5 -5
- package/dist/{chunk-52M2XF3W.js → chunk-RG3KDXMR.js} +16 -8
- package/dist/chunk-RG3KDXMR.js.map +1 -0
- package/dist/{chunk-MMFQNJPE.js → chunk-SXGBPQY6.js} +3 -3
- package/dist/chunk-SXGBPQY6.js.map +1 -0
- package/dist/{chunk-XUDTFI4M.js → chunk-T5DJCIUP.js} +2 -2
- package/dist/{chunk-AJJJE7F7.js → chunk-TQLDQ3XZ.js} +2 -2
- package/dist/{chunk-SZRK3VOR.js → chunk-WSMQ5GAP.js} +33 -21
- package/dist/chunk-WSMQ5GAP.js.map +1 -0
- package/dist/{chunk-WYVDNGJB.js → chunk-XMLCXRTS.js} +3 -3
- package/dist/{chunk-K6OLORQL.js → chunk-YEGPTBX5.js} +4 -4
- package/dist/{chunk-YHCYKUA3.js → chunk-ZFY5EMDV.js} +5 -5
- package/dist/{chunk-BKJHAJQW.js → chunk-ZYUASJUN.js} +7 -4
- package/dist/chunk-ZYUASJUN.js.map +1 -0
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +7 -6
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +7 -6
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +79 -138
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/index.js +7 -6
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +6 -5
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/show.js +7 -6
- package/dist/commands/diff.js +6 -5
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +11 -15
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +63 -69
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +13 -13
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +7 -6
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +14 -16
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +32 -30
- package/dist/commands/list.js +6 -5
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +7 -6
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +28 -11
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +7 -6
- package/dist/commands/outdated.js +6 -5
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +13 -11
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +9 -10
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +12 -8
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +20 -42
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +4 -3
- package/dist/components/wizard/category-grid.js +5 -3
- package/dist/components/wizard/category-grid.test.js +242 -194
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +5 -5
- package/dist/components/wizard/checkbox-grid.test.js +5 -5
- package/dist/components/wizard/domain-selection.js +12 -11
- package/dist/components/wizard/help-modal.js +3 -2
- package/dist/components/wizard/menu-item.js +1 -1
- package/dist/components/wizard/search-modal.js +3 -2
- package/dist/components/wizard/search-modal.test.js +3 -2
- package/dist/components/wizard/search-modal.test.js.map +1 -1
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +3 -3
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/selection-card.js +2 -2
- package/dist/components/wizard/source-grid.js +6 -4
- package/dist/components/wizard/source-grid.test.js +65 -40
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +9 -8
- package/dist/components/wizard/step-agents.js +11 -10
- package/dist/components/wizard/step-agents.test.js +28 -25
- package/dist/components/wizard/step-agents.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +12 -10
- package/dist/components/wizard/step-build.test.js +28 -34
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +6 -4
- package/dist/components/wizard/step-confirm.test.js +11 -15
- package/dist/components/wizard/step-confirm.test.js.map +1 -1
- package/dist/components/wizard/step-refine.js +3 -2
- package/dist/components/wizard/step-refine.test.js +3 -2
- package/dist/components/wizard/step-refine.test.js.map +1 -1
- package/dist/components/wizard/step-settings.js +10 -8
- package/dist/components/wizard/step-settings.test.js +17 -13
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +13 -11
- package/dist/components/wizard/step-sources.test.js +17 -14
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +15 -14
- package/dist/components/wizard/step-stack.test.js +42 -38
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- package/dist/components/wizard/view-title.js +2 -2
- package/dist/components/wizard/wizard-layout.js +10 -8
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard-tabs.test.js +2 -2
- package/dist/components/wizard/wizard.js +29 -27
- package/dist/hooks/init.js +32 -30
- package/dist/hooks/init.js.map +1 -1
- package/dist/{loader-2O32KKAQ.js → loader-4YOZCFIP.js} +4 -4
- package/dist/plugins/dummy-skill/.claude-plugin/.content-hash +1 -0
- package/dist/plugins/dummy-skill/.claude-plugin/plugin.json +13 -0
- package/dist/{source-loader-A6B3NDI4.js → source-loader-O5RMYUBW.js} +6 -5
- package/dist/{source-manager-Q7IQSGIX.js → source-manager-NKLL6HCL.js} +6 -5
- package/dist/stores/matrix-store.js +15 -0
- package/dist/stores/matrix-store.js.map +1 -0
- package/dist/stores/matrix-store.test.js +146 -0
- package/dist/stores/matrix-store.test.js.map +1 -0
- package/dist/stores/wizard-store.js +6 -5
- package/dist/stores/wizard-store.test.js +159 -107
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-52M2XF3W.js.map +0 -1
- package/dist/chunk-52XO4ULK.js.map +0 -1
- package/dist/chunk-6G3KZSO4.js.map +0 -1
- package/dist/chunk-7FMEMXJ4.js.map +0 -1
- package/dist/chunk-AX3SZZWA.js.map +0 -1
- package/dist/chunk-BFD5NZQ4.js.map +0 -1
- package/dist/chunk-BKJHAJQW.js.map +0 -1
- package/dist/chunk-BMJZBLP7.js.map +0 -1
- package/dist/chunk-EMIUPGPL.js.map +0 -1
- package/dist/chunk-G6WHCALR.js.map +0 -1
- package/dist/chunk-H7WJK7NJ.js.map +0 -1
- package/dist/chunk-KIWFEBKH.js.map +0 -1
- package/dist/chunk-MKCHLXMY.js.map +0 -1
- package/dist/chunk-MMFQNJPE.js.map +0 -1
- package/dist/chunk-MR6OBL3B.js.map +0 -1
- package/dist/chunk-O6BA7Q2B.js.map +0 -1
- package/dist/chunk-SDKCQXWE.js.map +0 -1
- package/dist/chunk-SEJF7CGJ.js.map +0 -1
- package/dist/chunk-SZRK3VOR.js.map +0 -1
- package/dist/chunk-TC3NHO34.js +0 -151
- package/dist/chunk-TC3NHO34.js.map +0 -1
- package/dist/chunk-TGLRDEEL.js.map +0 -1
- package/dist/chunk-TZXYBG3R.js.map +0 -1
- package/dist/chunk-WF6RM73R.js.map +0 -1
- /package/dist/{chunk-MGNYPVOJ.js.map → chunk-AQYAVLZK.js.map} +0 -0
- /package/dist/{chunk-BNQ5O6LE.js.map → chunk-AUNBGZS4.js.map} +0 -0
- /package/dist/{chunk-VR3CDXDT.js.map → chunk-EE5EPS32.js.map} +0 -0
- /package/dist/{chunk-OCEFD7V6.js.map → chunk-F3REOP7N.js.map} +0 -0
- /package/dist/{chunk-C577AJE7.js.map → chunk-FGLUQSVU.js.map} +0 -0
- /package/dist/{chunk-X5EG4EFP.js.map → chunk-MWGDG4QN.js.map} +0 -0
- /package/dist/{chunk-CIG7IKX3.js.map → chunk-OV5UJWS5.js.map} +0 -0
- /package/dist/{chunk-RO6LX3UV.js.map → chunk-R46CB36B.js.map} +0 -0
- /package/dist/{chunk-XUDTFI4M.js.map → chunk-T5DJCIUP.js.map} +0 -0
- /package/dist/{chunk-AJJJE7F7.js.map → chunk-TQLDQ3XZ.js.map} +0 -0
- /package/dist/{chunk-WYVDNGJB.js.map → chunk-XMLCXRTS.js.map} +0 -0
- /package/dist/{chunk-K6OLORQL.js.map → chunk-YEGPTBX5.js.map} +0 -0
- /package/dist/{chunk-YHCYKUA3.js.map → chunk-ZFY5EMDV.js.map} +0 -0
- /package/dist/{loader-2O32KKAQ.js.map → loader-4YOZCFIP.js.map} +0 -0
- /package/dist/{source-loader-A6B3NDI4.js.map → source-loader-O5RMYUBW.js.map} +0 -0
- /package/dist/{source-manager-Q7IQSGIX.js.map → source-manager-NKLL6HCL.js.map} +0 -0
|
@@ -12,8 +12,13 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
render
|
|
14
14
|
} from "../../chunk-66UDJBF6.js";
|
|
15
|
+
import {
|
|
16
|
+
createMockMatrix,
|
|
17
|
+
createMockSkill
|
|
18
|
+
} from "../../chunk-MOMI77PL.js";
|
|
15
19
|
import {
|
|
16
20
|
afterEach,
|
|
21
|
+
beforeEach,
|
|
17
22
|
describe,
|
|
18
23
|
globalExpect,
|
|
19
24
|
it,
|
|
@@ -21,10 +26,20 @@ import {
|
|
|
21
26
|
} from "../../chunk-XY3XDVMI.js";
|
|
22
27
|
import {
|
|
23
28
|
CategoryGrid
|
|
24
|
-
} from "../../chunk-
|
|
29
|
+
} from "../../chunk-CKPJTMNC.js";
|
|
25
30
|
import "../../chunk-GG4BSB6S.js";
|
|
26
|
-
import "../../chunk-
|
|
27
|
-
import "../../chunk-
|
|
31
|
+
import "../../chunk-AUNBGZS4.js";
|
|
32
|
+
import "../../chunk-4C7CSZC5.js";
|
|
33
|
+
import "../../chunk-6VIOO74O.js";
|
|
34
|
+
import "../../chunk-53URJ5XK.js";
|
|
35
|
+
import "../../chunk-F3REOP7N.js";
|
|
36
|
+
import "../../chunk-T4EXUIBY.js";
|
|
37
|
+
import {
|
|
38
|
+
useMatrixStore
|
|
39
|
+
} from "../../chunk-BKL3DF2Q.js";
|
|
40
|
+
import "../../chunk-LMZXL5RQ.js";
|
|
41
|
+
import "../../chunk-EGMQ3SXN.js";
|
|
42
|
+
import "../../chunk-EC3UJRKZ.js";
|
|
28
43
|
import {
|
|
29
44
|
init_esm_shims
|
|
30
45
|
} from "../../chunk-DHET7RCE.js";
|
|
@@ -32,9 +47,60 @@ import {
|
|
|
32
47
|
// src/cli/components/wizard/category-grid.test.tsx
|
|
33
48
|
init_esm_shims();
|
|
34
49
|
import { jsx } from "react/jsx-runtime";
|
|
35
|
-
var
|
|
50
|
+
var TEST_GRID_SKILLS = [
|
|
51
|
+
{ id: "web-framework-react", displayName: "React", category: "web-framework" },
|
|
52
|
+
{ id: "web-framework-vue-composition-api", displayName: "Vue", category: "web-framework" },
|
|
53
|
+
{ id: "web-framework-angular-standalone", displayName: "Angular", category: "web-framework" },
|
|
54
|
+
{ id: "web-framework-solidjs", displayName: "SolidJS", category: "web-framework" },
|
|
55
|
+
{ id: "web-framework-nuxt", displayName: "Nuxt", category: "web-framework" },
|
|
56
|
+
{ id: "web-framework-remix", displayName: "Remix", category: "web-framework" },
|
|
57
|
+
{
|
|
58
|
+
id: "web-framework-nextjs-app-router",
|
|
59
|
+
displayName: "Next.js App Router",
|
|
60
|
+
category: "web-framework"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "web-framework-nextjs-server-actions",
|
|
64
|
+
displayName: "Next.js Server Actions",
|
|
65
|
+
category: "web-framework"
|
|
66
|
+
},
|
|
67
|
+
{ id: "web-styling-scss-modules", displayName: "SCSS Modules", category: "web-styling" },
|
|
68
|
+
{ id: "web-styling-tailwind", displayName: "Tailwind", category: "web-styling" },
|
|
69
|
+
{ id: "web-styling-cva", displayName: "CVA", category: "web-styling" },
|
|
70
|
+
{ id: "web-state-zustand", displayName: "Zustand", category: "web-client-state" },
|
|
71
|
+
{ id: "web-state-jotai", displayName: "Jotai", category: "web-client-state" },
|
|
72
|
+
{ id: "web-state-redux-toolkit", displayName: "Redux", category: "web-client-state" },
|
|
73
|
+
{ id: "web-state-mobx", displayName: "MobX", category: "web-client-state" },
|
|
74
|
+
{ id: "web-server-state-react-query", displayName: "React Query", category: "web-server-state" },
|
|
75
|
+
{ id: "web-data-fetching-swr", displayName: "SWR", category: "web-server-state" },
|
|
76
|
+
{ id: "web-data-fetching-graphql-apollo", displayName: "Apollo", category: "web-server-state" },
|
|
77
|
+
{ id: "api-analytics-posthog-analytics", displayName: "PostHog", category: "api-analytics" },
|
|
78
|
+
{ id: "web-forms-react-hook-form", displayName: "React Hook Form", category: "web-forms" },
|
|
79
|
+
{ id: "web-forms-vee-validate", displayName: "Vee Validate", category: "web-forms" },
|
|
80
|
+
{ id: "web-forms-zod-validation", displayName: "Zod Validation", category: "web-forms" },
|
|
81
|
+
{ id: "web-testing-vitest", displayName: "Vitest", category: "web-testing" },
|
|
82
|
+
{ id: "web-testing-playwright-e2e", displayName: "Playwright", category: "web-testing" },
|
|
83
|
+
{ id: "web-testing-cypress-e2e", displayName: "Cypress", category: "web-testing" },
|
|
84
|
+
{ id: "web-mocks-msw", displayName: "MSW", category: "web-mocking" },
|
|
85
|
+
{
|
|
86
|
+
id: "web-testing-react-testing-library",
|
|
87
|
+
displayName: "React Testing Library",
|
|
88
|
+
category: "web-testing"
|
|
89
|
+
},
|
|
90
|
+
{ id: "web-testing-vue-test-utils", displayName: "Vue Test Utils", category: "web-testing" },
|
|
91
|
+
{ id: "web-i18n-next-intl", displayName: "Next Intl", category: "web-i18n" },
|
|
92
|
+
{ id: "web-i18n-react-intl", displayName: "React Intl", category: "web-i18n" },
|
|
93
|
+
{ id: "web-i18n-vue-i18n", displayName: "Vue I18n", category: "web-i18n" }
|
|
94
|
+
];
|
|
95
|
+
function buildTestMatrix() {
|
|
96
|
+
const skills = {};
|
|
97
|
+
for (const { id, displayName, category } of TEST_GRID_SKILLS) {
|
|
98
|
+
skills[id] = createMockSkill(id, { displayName, category });
|
|
99
|
+
}
|
|
100
|
+
return createMockMatrix(skills);
|
|
101
|
+
}
|
|
102
|
+
var createOption = (id, overrides = {}) => ({
|
|
36
103
|
id,
|
|
37
|
-
label,
|
|
38
104
|
state: "normal",
|
|
39
105
|
selected: false,
|
|
40
106
|
...overrides
|
|
@@ -52,13 +118,13 @@ var defaultCategories = [
|
|
|
52
118
|
"web-framework",
|
|
53
119
|
"Framework",
|
|
54
120
|
[
|
|
55
|
-
createOption("web-framework-react",
|
|
121
|
+
createOption("web-framework-react", {
|
|
56
122
|
state: "recommended",
|
|
57
123
|
stateReason: "Popular choice"
|
|
58
124
|
}),
|
|
59
|
-
createOption("web-framework-vue-composition-api"
|
|
60
|
-
createOption("web-framework-angular-standalone"
|
|
61
|
-
createOption("web-framework-solidjs"
|
|
125
|
+
createOption("web-framework-vue-composition-api"),
|
|
126
|
+
createOption("web-framework-angular-standalone"),
|
|
127
|
+
createOption("web-framework-solidjs")
|
|
62
128
|
],
|
|
63
129
|
{ required: true }
|
|
64
130
|
),
|
|
@@ -66,45 +132,43 @@ var defaultCategories = [
|
|
|
66
132
|
"web-styling",
|
|
67
133
|
"Styling",
|
|
68
134
|
[
|
|
69
|
-
createOption("web-styling-scss-modules",
|
|
70
|
-
createOption("web-styling-tailwind",
|
|
71
|
-
createOption("web-styling-cva"
|
|
72
|
-
createOption("web-framework-nuxt"
|
|
135
|
+
createOption("web-styling-scss-modules", { selected: true }),
|
|
136
|
+
createOption("web-styling-tailwind", { state: "recommended" }),
|
|
137
|
+
createOption("web-styling-cva"),
|
|
138
|
+
createOption("web-framework-nuxt")
|
|
73
139
|
],
|
|
74
140
|
{ required: true }
|
|
75
141
|
),
|
|
76
142
|
createCategory("web-client-state", "Client State", [
|
|
77
|
-
createOption("web-state-zustand",
|
|
78
|
-
createOption("web-state-jotai"
|
|
79
|
-
createOption("web-state-redux-toolkit",
|
|
143
|
+
createOption("web-state-zustand", { state: "recommended" }),
|
|
144
|
+
createOption("web-state-jotai"),
|
|
145
|
+
createOption("web-state-redux-toolkit", {
|
|
80
146
|
state: "discouraged",
|
|
81
147
|
stateReason: "Complex for most apps"
|
|
82
148
|
}),
|
|
83
|
-
createOption("web-state-mobx"
|
|
149
|
+
createOption("web-state-mobx")
|
|
84
150
|
]),
|
|
85
151
|
createCategory("web-server-state", "Server State", [
|
|
86
|
-
createOption("web-server-state-react-query",
|
|
87
|
-
createOption("web-data-fetching-swr"
|
|
88
|
-
createOption("web-data-fetching-graphql-apollo"
|
|
152
|
+
createOption("web-server-state-react-query", { selected: true }),
|
|
153
|
+
createOption("web-data-fetching-swr"),
|
|
154
|
+
createOption("web-data-fetching-graphql-apollo")
|
|
89
155
|
]),
|
|
90
|
-
createCategory("api-analytics", "Analytics", [
|
|
91
|
-
createOption("api-analytics-posthog-analytics", "PostHog")
|
|
92
|
-
])
|
|
156
|
+
createCategory("api-analytics", "Analytics", [createOption("api-analytics-posthog-analytics")])
|
|
93
157
|
];
|
|
94
158
|
var categoriesWithFramework = [
|
|
95
159
|
createCategory(
|
|
96
160
|
"web-framework",
|
|
97
161
|
"Framework",
|
|
98
162
|
[
|
|
99
|
-
createOption("web-framework-react",
|
|
163
|
+
createOption("web-framework-react", {
|
|
100
164
|
state: "recommended",
|
|
101
165
|
stateReason: "Popular choice",
|
|
102
166
|
selected: true
|
|
103
167
|
// Framework selected
|
|
104
168
|
}),
|
|
105
|
-
createOption("web-framework-vue-composition-api"
|
|
106
|
-
createOption("web-framework-angular-standalone"
|
|
107
|
-
createOption("web-framework-solidjs"
|
|
169
|
+
createOption("web-framework-vue-composition-api"),
|
|
170
|
+
createOption("web-framework-angular-standalone"),
|
|
171
|
+
createOption("web-framework-solidjs")
|
|
108
172
|
],
|
|
109
173
|
{ required: true }
|
|
110
174
|
),
|
|
@@ -112,75 +176,69 @@ var categoriesWithFramework = [
|
|
|
112
176
|
"web-styling",
|
|
113
177
|
"Styling",
|
|
114
178
|
[
|
|
115
|
-
createOption("web-styling-scss-modules"
|
|
116
|
-
createOption("web-styling-tailwind",
|
|
117
|
-
createOption("web-styling-cva"
|
|
118
|
-
createOption("web-framework-nuxt"
|
|
179
|
+
createOption("web-styling-scss-modules"),
|
|
180
|
+
createOption("web-styling-tailwind", { state: "recommended" }),
|
|
181
|
+
createOption("web-styling-cva"),
|
|
182
|
+
createOption("web-framework-nuxt")
|
|
119
183
|
],
|
|
120
184
|
{ required: true }
|
|
121
185
|
),
|
|
122
186
|
createCategory("web-client-state", "Client State", [
|
|
123
|
-
createOption("web-state-zustand",
|
|
124
|
-
createOption("web-state-jotai"
|
|
125
|
-
createOption("web-state-redux-toolkit",
|
|
126
|
-
createOption("web-state-mobx"
|
|
187
|
+
createOption("web-state-zustand", { state: "recommended" }),
|
|
188
|
+
createOption("web-state-jotai"),
|
|
189
|
+
createOption("web-state-redux-toolkit", { state: "discouraged" }),
|
|
190
|
+
createOption("web-state-mobx")
|
|
127
191
|
])
|
|
128
192
|
];
|
|
129
193
|
var manyCategories = [
|
|
130
194
|
createCategory("web-framework", "Category 0", [
|
|
131
|
-
createOption("web-framework-react"
|
|
132
|
-
createOption("web-framework-vue-composition-api"
|
|
133
|
-
createOption("web-framework-angular-standalone"
|
|
195
|
+
createOption("web-framework-react"),
|
|
196
|
+
createOption("web-framework-vue-composition-api"),
|
|
197
|
+
createOption("web-framework-angular-standalone")
|
|
134
198
|
]),
|
|
135
199
|
createCategory("web-styling", "Category 1", [
|
|
136
|
-
createOption("web-styling-tailwind"
|
|
137
|
-
createOption("web-styling-scss-modules"
|
|
138
|
-
createOption("web-styling-cva"
|
|
200
|
+
createOption("web-styling-tailwind"),
|
|
201
|
+
createOption("web-styling-scss-modules"),
|
|
202
|
+
createOption("web-styling-cva")
|
|
139
203
|
]),
|
|
140
204
|
createCategory("web-client-state", "Category 2", [
|
|
141
|
-
createOption("web-state-zustand"
|
|
142
|
-
createOption("web-state-jotai"
|
|
143
|
-
createOption("web-state-mobx"
|
|
205
|
+
createOption("web-state-zustand"),
|
|
206
|
+
createOption("web-state-jotai"),
|
|
207
|
+
createOption("web-state-mobx")
|
|
144
208
|
]),
|
|
145
209
|
createCategory("web-server-state", "Category 3", [
|
|
146
|
-
createOption("web-server-state-react-query"
|
|
147
|
-
createOption("web-data-fetching-swr"
|
|
148
|
-
createOption("web-data-fetching-graphql-apollo"
|
|
210
|
+
createOption("web-server-state-react-query"),
|
|
211
|
+
createOption("web-data-fetching-swr"),
|
|
212
|
+
createOption("web-data-fetching-graphql-apollo")
|
|
149
213
|
]),
|
|
150
214
|
createCategory("web-forms", "Category 4", [
|
|
151
|
-
createOption("web-forms-react-hook-form"
|
|
152
|
-
createOption("web-forms-vee-validate"
|
|
153
|
-
createOption("web-forms-zod-validation"
|
|
215
|
+
createOption("web-forms-react-hook-form"),
|
|
216
|
+
createOption("web-forms-vee-validate"),
|
|
217
|
+
createOption("web-forms-zod-validation")
|
|
154
218
|
]),
|
|
155
219
|
createCategory("web-testing", "Category 5", [
|
|
156
|
-
createOption("web-testing-vitest"
|
|
157
|
-
createOption("web-testing-playwright-e2e"
|
|
158
|
-
createOption("web-testing-cypress-e2e"
|
|
220
|
+
createOption("web-testing-vitest"),
|
|
221
|
+
createOption("web-testing-playwright-e2e"),
|
|
222
|
+
createOption("web-testing-cypress-e2e")
|
|
159
223
|
]),
|
|
160
224
|
createCategory("web-mocking", "Category 6", [
|
|
161
|
-
createOption("web-mocks-msw"
|
|
162
|
-
createOption("web-testing-react-testing-library"
|
|
163
|
-
createOption("web-testing-vue-test-utils"
|
|
225
|
+
createOption("web-mocks-msw"),
|
|
226
|
+
createOption("web-testing-react-testing-library"),
|
|
227
|
+
createOption("web-testing-vue-test-utils")
|
|
164
228
|
]),
|
|
165
229
|
createCategory("web-i18n", "Category 7", [
|
|
166
|
-
createOption("web-i18n-next-intl"
|
|
167
|
-
createOption("web-i18n-react-intl"
|
|
168
|
-
createOption("web-i18n-vue-i18n"
|
|
230
|
+
createOption("web-i18n-next-intl"),
|
|
231
|
+
createOption("web-i18n-react-intl"),
|
|
232
|
+
createOption("web-i18n-vue-i18n")
|
|
169
233
|
])
|
|
170
234
|
];
|
|
171
235
|
var navCategories = [
|
|
172
|
-
createCategory("web-framework", "Category 0", [createOption("web-framework-react"
|
|
173
|
-
createCategory("web-styling", "Category 1", [createOption("web-styling-tailwind"
|
|
174
|
-
createCategory("web-client-state", "Category 2", [
|
|
175
|
-
|
|
176
|
-
]),
|
|
177
|
-
createCategory("web-
|
|
178
|
-
createOption("web-server-state-react-query", "Option 3A")
|
|
179
|
-
]),
|
|
180
|
-
createCategory("web-forms", "Category 4", [
|
|
181
|
-
createOption("web-forms-react-hook-form", "Option 4A")
|
|
182
|
-
]),
|
|
183
|
-
createCategory("web-testing", "Category 5", [createOption("web-testing-vitest", "Option 5A")])
|
|
236
|
+
createCategory("web-framework", "Category 0", [createOption("web-framework-react")]),
|
|
237
|
+
createCategory("web-styling", "Category 1", [createOption("web-styling-tailwind")]),
|
|
238
|
+
createCategory("web-client-state", "Category 2", [createOption("web-state-zustand")]),
|
|
239
|
+
createCategory("web-server-state", "Category 3", [createOption("web-server-state-react-query")]),
|
|
240
|
+
createCategory("web-forms", "Category 4", [createOption("web-forms-react-hook-form")]),
|
|
241
|
+
createCategory("web-testing", "Category 5", [createOption("web-testing-vitest")])
|
|
184
242
|
];
|
|
185
243
|
var defaultProps = {
|
|
186
244
|
categories: defaultCategories,
|
|
@@ -196,9 +254,13 @@ var renderGrid = (props = {}) => {
|
|
|
196
254
|
};
|
|
197
255
|
describe("CategoryGrid component", () => {
|
|
198
256
|
let cleanup;
|
|
257
|
+
beforeEach(() => {
|
|
258
|
+
useMatrixStore.getState().setMatrix(buildTestMatrix());
|
|
259
|
+
});
|
|
199
260
|
afterEach(() => {
|
|
200
261
|
cleanup?.();
|
|
201
262
|
cleanup = void 0;
|
|
263
|
+
useMatrixStore.getState().reset();
|
|
202
264
|
});
|
|
203
265
|
describe("rendering", () => {
|
|
204
266
|
it("should render all categories as sections", () => {
|
|
@@ -248,14 +310,14 @@ describe("CategoryGrid component", () => {
|
|
|
248
310
|
});
|
|
249
311
|
});
|
|
250
312
|
describe("visual states", () => {
|
|
251
|
-
it("should show selected options with
|
|
313
|
+
it("should show selected options with display name", () => {
|
|
252
314
|
const { lastFrame, unmount } = renderGrid();
|
|
253
315
|
cleanup = unmount;
|
|
254
316
|
const output = lastFrame();
|
|
255
317
|
globalExpect(output).toContain("SCSS Modules");
|
|
256
318
|
globalExpect(output).toContain("React Query");
|
|
257
319
|
});
|
|
258
|
-
it("should show unselected options with
|
|
320
|
+
it("should show unselected options with display name", () => {
|
|
259
321
|
const { lastFrame, unmount } = renderGrid();
|
|
260
322
|
cleanup = unmount;
|
|
261
323
|
const output = lastFrame();
|
|
@@ -277,30 +339,30 @@ describe("CategoryGrid component", () => {
|
|
|
277
339
|
it("should show discouraged options with warning styling", () => {
|
|
278
340
|
const categories = [
|
|
279
341
|
createCategory("web-testing", "Test", [
|
|
280
|
-
createOption("web-forms-react-hook-form"
|
|
281
|
-
createOption("web-forms-vee-validate",
|
|
342
|
+
createOption("web-forms-react-hook-form"),
|
|
343
|
+
createOption("web-forms-vee-validate", { state: "discouraged" })
|
|
282
344
|
])
|
|
283
345
|
];
|
|
284
346
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
285
347
|
cleanup = unmount;
|
|
286
348
|
const output = lastFrame();
|
|
287
|
-
globalExpect(output).toContain("
|
|
349
|
+
globalExpect(output).toContain("Vee Validate");
|
|
288
350
|
});
|
|
289
|
-
it("should render selected skills with
|
|
351
|
+
it("should render selected skills with display name", () => {
|
|
290
352
|
const categories = [
|
|
291
353
|
createCategory("web-forms", "Forms", [
|
|
292
|
-
createOption("web-forms-react-hook-form",
|
|
354
|
+
createOption("web-forms-react-hook-form", { selected: true })
|
|
293
355
|
])
|
|
294
356
|
];
|
|
295
357
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
296
358
|
cleanup = unmount;
|
|
297
359
|
const output = lastFrame();
|
|
298
|
-
globalExpect(output).toContain("
|
|
360
|
+
globalExpect(output).toContain("React Hook Form");
|
|
299
361
|
});
|
|
300
|
-
it("should render unselected skills with
|
|
362
|
+
it("should render unselected skills with display name", () => {
|
|
301
363
|
const categories = [
|
|
302
364
|
createCategory("web-forms", "Forms", [
|
|
303
|
-
createOption("web-forms-react-hook-form",
|
|
365
|
+
createOption("web-forms-react-hook-form", {
|
|
304
366
|
state: "normal",
|
|
305
367
|
selected: false
|
|
306
368
|
})
|
|
@@ -309,27 +371,27 @@ describe("CategoryGrid component", () => {
|
|
|
309
371
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
310
372
|
cleanup = unmount;
|
|
311
373
|
const output = lastFrame();
|
|
312
|
-
globalExpect(output).toContain("
|
|
374
|
+
globalExpect(output).toContain("React Hook Form");
|
|
313
375
|
});
|
|
314
|
-
it("should render discouraged skills with
|
|
376
|
+
it("should render discouraged skills with display name", () => {
|
|
315
377
|
const categories = [
|
|
316
378
|
createCategory("web-forms", "Forms", [
|
|
317
|
-
createOption("web-forms-react-hook-form",
|
|
379
|
+
createOption("web-forms-react-hook-form", { state: "discouraged" })
|
|
318
380
|
])
|
|
319
381
|
];
|
|
320
382
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
321
383
|
cleanup = unmount;
|
|
322
384
|
const output = lastFrame();
|
|
323
|
-
globalExpect(output).toContain("
|
|
385
|
+
globalExpect(output).toContain("React Hook Form");
|
|
324
386
|
});
|
|
325
|
-
it("should render discouraged+selected skills with
|
|
387
|
+
it("should render discouraged+selected skills with display name", () => {
|
|
326
388
|
const categories = [
|
|
327
389
|
createCategory("web-forms", "Forms", [
|
|
328
|
-
createOption("web-forms-react-hook-form",
|
|
390
|
+
createOption("web-forms-react-hook-form", {
|
|
329
391
|
state: "discouraged",
|
|
330
392
|
selected: true
|
|
331
393
|
}),
|
|
332
|
-
createOption("web-forms-vee-validate",
|
|
394
|
+
createOption("web-forms-vee-validate", {
|
|
333
395
|
state: "discouraged",
|
|
334
396
|
selected: false
|
|
335
397
|
})
|
|
@@ -338,37 +400,37 @@ describe("CategoryGrid component", () => {
|
|
|
338
400
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
339
401
|
cleanup = unmount;
|
|
340
402
|
const output = lastFrame();
|
|
341
|
-
globalExpect(output).toContain("
|
|
342
|
-
globalExpect(output).toContain("
|
|
403
|
+
globalExpect(output).toContain("React Hook Form");
|
|
404
|
+
globalExpect(output).toContain("Vee Validate");
|
|
343
405
|
});
|
|
344
|
-
it("should render discouraged skills with
|
|
406
|
+
it("should render discouraged skills with display name from store", () => {
|
|
345
407
|
const categories = [
|
|
346
408
|
createCategory("web-forms", "Forms", [
|
|
347
|
-
createOption("web-forms-react-hook-form",
|
|
409
|
+
createOption("web-forms-react-hook-form", { state: "discouraged" })
|
|
348
410
|
])
|
|
349
411
|
];
|
|
350
412
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
351
413
|
cleanup = unmount;
|
|
352
414
|
const output = lastFrame();
|
|
353
|
-
globalExpect(output).toContain("
|
|
415
|
+
globalExpect(output).toContain("React Hook Form");
|
|
354
416
|
});
|
|
355
|
-
it("should render both selected and unselected skills with
|
|
417
|
+
it("should render both selected and unselected skills with display names", () => {
|
|
356
418
|
const categories = [
|
|
357
419
|
createCategory("web-forms", "Forms", [
|
|
358
|
-
createOption("web-forms-react-hook-form",
|
|
359
|
-
createOption("web-forms-vee-validate",
|
|
420
|
+
createOption("web-forms-react-hook-form", { selected: true }),
|
|
421
|
+
createOption("web-forms-vee-validate", { selected: false })
|
|
360
422
|
])
|
|
361
423
|
];
|
|
362
424
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
363
425
|
cleanup = unmount;
|
|
364
426
|
const output = lastFrame();
|
|
365
|
-
globalExpect(output).toContain("
|
|
366
|
-
globalExpect(output).toContain("
|
|
427
|
+
globalExpect(output).toContain("React Hook Form");
|
|
428
|
+
globalExpect(output).toContain("Vee Validate");
|
|
367
429
|
});
|
|
368
|
-
it("should render skill
|
|
430
|
+
it("should render skill display name regardless of selection state", () => {
|
|
369
431
|
const categories1 = [
|
|
370
432
|
createCategory("web-forms", "Forms", [
|
|
371
|
-
createOption("web-forms-react-hook-form",
|
|
433
|
+
createOption("web-forms-react-hook-form", { selected: false })
|
|
372
434
|
])
|
|
373
435
|
];
|
|
374
436
|
const { lastFrame: frame1, unmount: unmount1 } = renderGrid({ categories: categories1 });
|
|
@@ -376,14 +438,14 @@ describe("CategoryGrid component", () => {
|
|
|
376
438
|
unmount1();
|
|
377
439
|
const categories2 = [
|
|
378
440
|
createCategory("web-forms", "Forms", [
|
|
379
|
-
createOption("web-forms-react-hook-form",
|
|
441
|
+
createOption("web-forms-react-hook-form", { selected: true })
|
|
380
442
|
])
|
|
381
443
|
];
|
|
382
444
|
const { lastFrame: frame2, unmount: unmount2 } = renderGrid({ categories: categories2 });
|
|
383
445
|
cleanup = unmount2;
|
|
384
446
|
const output2 = frame2();
|
|
385
|
-
globalExpect(output1).toContain("
|
|
386
|
-
globalExpect(output2).toContain("
|
|
447
|
+
globalExpect(output1).toContain("React Hook Form");
|
|
448
|
+
globalExpect(output2).toContain("React Hook Form");
|
|
387
449
|
});
|
|
388
450
|
});
|
|
389
451
|
describe("locked sections", () => {
|
|
@@ -408,10 +470,10 @@ describe("CategoryGrid component", () => {
|
|
|
408
470
|
it("should not lock any sections when no framework category exists", () => {
|
|
409
471
|
const categoriesNoFramework = [
|
|
410
472
|
createCategory("web-styling", "Styling", [
|
|
411
|
-
createOption("web-styling-scss-modules"
|
|
412
|
-
createOption("web-styling-tailwind"
|
|
473
|
+
createOption("web-styling-scss-modules"),
|
|
474
|
+
createOption("web-styling-tailwind")
|
|
413
475
|
]),
|
|
414
|
-
createCategory("web-client-state", "State", [createOption("web-state-zustand"
|
|
476
|
+
createCategory("web-client-state", "State", [createOption("web-state-zustand")])
|
|
415
477
|
];
|
|
416
478
|
const { lastFrame, unmount } = renderGrid({
|
|
417
479
|
categories: categoriesNoFramework
|
|
@@ -423,7 +485,7 @@ describe("CategoryGrid component", () => {
|
|
|
423
485
|
});
|
|
424
486
|
});
|
|
425
487
|
describe("focus indicator", () => {
|
|
426
|
-
it("should render focused option with
|
|
488
|
+
it("should render focused option with display name", () => {
|
|
427
489
|
const { lastFrame, unmount } = renderGrid({
|
|
428
490
|
defaultFocusedRow: 0,
|
|
429
491
|
defaultFocusedCol: 0
|
|
@@ -635,8 +697,8 @@ describe("CategoryGrid component", () => {
|
|
|
635
697
|
"web-framework",
|
|
636
698
|
"Framework",
|
|
637
699
|
[
|
|
638
|
-
createOption("web-framework-react",
|
|
639
|
-
createOption("web-framework-vue-composition-api"
|
|
700
|
+
createOption("web-framework-react", { selected: true }),
|
|
701
|
+
createOption("web-framework-vue-composition-api")
|
|
640
702
|
],
|
|
641
703
|
{ required: true }
|
|
642
704
|
)
|
|
@@ -658,8 +720,8 @@ describe("CategoryGrid component", () => {
|
|
|
658
720
|
const onToggle = vi.fn();
|
|
659
721
|
const categories = [
|
|
660
722
|
createCategory("web-testing", "Test", [
|
|
661
|
-
createOption("web-forms-react-hook-form",
|
|
662
|
-
createOption("web-forms-vee-validate",
|
|
723
|
+
createOption("web-forms-react-hook-form", { state: "discouraged" }),
|
|
724
|
+
createOption("web-forms-vee-validate", { state: "discouraged" })
|
|
663
725
|
])
|
|
664
726
|
];
|
|
665
727
|
const { stdin, unmount } = renderGrid({
|
|
@@ -692,9 +754,9 @@ describe("CategoryGrid component", () => {
|
|
|
692
754
|
const onFocusChange = vi.fn();
|
|
693
755
|
const categories = [
|
|
694
756
|
createCategory("web-testing", "Test", [
|
|
695
|
-
createOption("web-forms-react-hook-form"
|
|
696
|
-
createOption("web-forms-vee-validate",
|
|
697
|
-
createOption("web-forms-zod-validation"
|
|
757
|
+
createOption("web-forms-react-hook-form"),
|
|
758
|
+
createOption("web-forms-vee-validate", { state: "discouraged" }),
|
|
759
|
+
createOption("web-forms-zod-validation")
|
|
698
760
|
])
|
|
699
761
|
];
|
|
700
762
|
const { stdin, unmount } = renderGrid({
|
|
@@ -713,9 +775,9 @@ describe("CategoryGrid component", () => {
|
|
|
713
775
|
const onFocusChange = vi.fn();
|
|
714
776
|
const categories = [
|
|
715
777
|
createCategory("web-testing", "Test", [
|
|
716
|
-
createOption("web-forms-react-hook-form"
|
|
717
|
-
createOption("web-forms-vee-validate",
|
|
718
|
-
createOption("web-forms-zod-validation"
|
|
778
|
+
createOption("web-forms-react-hook-form"),
|
|
779
|
+
createOption("web-forms-vee-validate", { state: "discouraged" }),
|
|
780
|
+
createOption("web-forms-zod-validation")
|
|
719
781
|
])
|
|
720
782
|
];
|
|
721
783
|
const { stdin, unmount } = renderGrid({
|
|
@@ -735,8 +797,8 @@ describe("CategoryGrid component", () => {
|
|
|
735
797
|
const onFocusChange = vi.fn();
|
|
736
798
|
const categories = [
|
|
737
799
|
createCategory("web-testing", "Test", [
|
|
738
|
-
createOption("web-forms-react-hook-form",
|
|
739
|
-
createOption("web-forms-vee-validate",
|
|
800
|
+
createOption("web-forms-react-hook-form", { state: "discouraged" }),
|
|
801
|
+
createOption("web-forms-vee-validate", { state: "discouraged" })
|
|
740
802
|
])
|
|
741
803
|
];
|
|
742
804
|
const { stdin, unmount } = renderGrid({
|
|
@@ -833,8 +895,8 @@ describe("CategoryGrid component", () => {
|
|
|
833
895
|
it("should show discouraged label for discouraged options when showLabels is true", () => {
|
|
834
896
|
const categories = [
|
|
835
897
|
createCategory("web-testing", "Test", [
|
|
836
|
-
createOption("web-forms-react-hook-form"
|
|
837
|
-
createOption("web-forms-vee-validate",
|
|
898
|
+
createOption("web-forms-react-hook-form"),
|
|
899
|
+
createOption("web-forms-vee-validate", { state: "discouraged" })
|
|
838
900
|
])
|
|
839
901
|
];
|
|
840
902
|
const { lastFrame, unmount } = renderGrid({ categories, showLabels: true });
|
|
@@ -847,10 +909,10 @@ describe("CategoryGrid component", () => {
|
|
|
847
909
|
it("should preserve original order regardless of state", () => {
|
|
848
910
|
const categories = [
|
|
849
911
|
createCategory("web-client-state", "State", [
|
|
850
|
-
createOption("web-state-jotai"
|
|
851
|
-
createOption("web-state-zustand",
|
|
852
|
-
createOption("web-state-redux-toolkit",
|
|
853
|
-
createOption("web-state-mobx"
|
|
912
|
+
createOption("web-state-jotai"),
|
|
913
|
+
createOption("web-state-zustand", { state: "recommended" }),
|
|
914
|
+
createOption("web-state-redux-toolkit", { state: "discouraged" }),
|
|
915
|
+
createOption("web-state-mobx")
|
|
854
916
|
])
|
|
855
917
|
];
|
|
856
918
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
@@ -867,16 +929,16 @@ describe("CategoryGrid component", () => {
|
|
|
867
929
|
it("should not change order when a skill is selected", () => {
|
|
868
930
|
const categoriesBefore = [
|
|
869
931
|
createCategory("web-client-state", "State", [
|
|
870
|
-
createOption("web-state-jotai"
|
|
871
|
-
createOption("web-state-zustand"
|
|
872
|
-
createOption("web-state-redux-toolkit"
|
|
932
|
+
createOption("web-state-jotai"),
|
|
933
|
+
createOption("web-state-zustand"),
|
|
934
|
+
createOption("web-state-redux-toolkit")
|
|
873
935
|
])
|
|
874
936
|
];
|
|
875
937
|
const categoriesAfter = [
|
|
876
938
|
createCategory("web-client-state", "State", [
|
|
877
|
-
createOption("web-state-jotai"
|
|
878
|
-
createOption("web-state-zustand",
|
|
879
|
-
createOption("web-state-redux-toolkit"
|
|
939
|
+
createOption("web-state-jotai"),
|
|
940
|
+
createOption("web-state-zustand", { selected: true }),
|
|
941
|
+
createOption("web-state-redux-toolkit")
|
|
880
942
|
])
|
|
881
943
|
];
|
|
882
944
|
const { lastFrame: frameBefore, unmount: unmountBefore } = renderGrid({
|
|
@@ -897,16 +959,16 @@ describe("CategoryGrid component", () => {
|
|
|
897
959
|
it("should not change order when a skill state changes from normal to discouraged", () => {
|
|
898
960
|
const categoriesBefore = [
|
|
899
961
|
createCategory("web-client-state", "State", [
|
|
900
|
-
createOption("web-state-jotai"
|
|
901
|
-
createOption("web-state-zustand"
|
|
902
|
-
createOption("web-state-redux-toolkit"
|
|
962
|
+
createOption("web-state-jotai"),
|
|
963
|
+
createOption("web-state-zustand"),
|
|
964
|
+
createOption("web-state-redux-toolkit")
|
|
903
965
|
])
|
|
904
966
|
];
|
|
905
967
|
const categoriesAfter = [
|
|
906
968
|
createCategory("web-client-state", "State", [
|
|
907
|
-
createOption("web-state-jotai"
|
|
908
|
-
createOption("web-state-zustand",
|
|
909
|
-
createOption("web-state-redux-toolkit"
|
|
969
|
+
createOption("web-state-jotai"),
|
|
970
|
+
createOption("web-state-zustand", { state: "discouraged" }),
|
|
971
|
+
createOption("web-state-redux-toolkit")
|
|
910
972
|
])
|
|
911
973
|
];
|
|
912
974
|
const { lastFrame: frameBefore, unmount: unmountBefore } = renderGrid({
|
|
@@ -928,26 +990,22 @@ describe("CategoryGrid component", () => {
|
|
|
928
990
|
describe("edge cases", () => {
|
|
929
991
|
it("should handle single category", () => {
|
|
930
992
|
const categories = [
|
|
931
|
-
createCategory("web-forms", "Single Category", [
|
|
932
|
-
createOption("web-forms-react-hook-form", "Option 1")
|
|
933
|
-
])
|
|
993
|
+
createCategory("web-forms", "Single Category", [createOption("web-forms-react-hook-form")])
|
|
934
994
|
];
|
|
935
995
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
936
996
|
cleanup = unmount;
|
|
937
997
|
const output = lastFrame();
|
|
938
998
|
globalExpect(output).toContain("Single Category");
|
|
939
|
-
globalExpect(output).toContain("
|
|
999
|
+
globalExpect(output).toContain("React Hook Form");
|
|
940
1000
|
});
|
|
941
1001
|
it("should handle single option in category", () => {
|
|
942
1002
|
const categories = [
|
|
943
|
-
createCategory("web-forms", "Single", [
|
|
944
|
-
createOption("web-forms-react-hook-form", "Only Option")
|
|
945
|
-
])
|
|
1003
|
+
createCategory("web-forms", "Single", [createOption("web-forms-react-hook-form")])
|
|
946
1004
|
];
|
|
947
1005
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
948
1006
|
cleanup = unmount;
|
|
949
1007
|
const output = lastFrame();
|
|
950
|
-
globalExpect(output).toContain("
|
|
1008
|
+
globalExpect(output).toContain("React Hook Form");
|
|
951
1009
|
});
|
|
952
1010
|
it("should handle category with many options (flows naturally)", () => {
|
|
953
1011
|
const manySkillIds = [
|
|
@@ -962,40 +1020,38 @@ describe("CategoryGrid component", () => {
|
|
|
962
1020
|
"web-styling-tailwind",
|
|
963
1021
|
"web-styling-scss-modules"
|
|
964
1022
|
];
|
|
965
|
-
const options = manySkillIds.map((id
|
|
1023
|
+
const options = manySkillIds.map((id) => createOption(id));
|
|
966
1024
|
const categories = [createCategory("web-mocking", "Many Options", options)];
|
|
967
1025
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
968
1026
|
cleanup = unmount;
|
|
969
1027
|
const output = lastFrame();
|
|
970
1028
|
globalExpect(output).toContain("Many Options");
|
|
971
|
-
globalExpect(output).toContain("
|
|
972
|
-
globalExpect(output).toContain("
|
|
1029
|
+
globalExpect(output).toContain("React");
|
|
1030
|
+
globalExpect(output).toContain("SCSS Modules");
|
|
973
1031
|
});
|
|
974
|
-
it("should handle long
|
|
1032
|
+
it("should handle long display names", () => {
|
|
975
1033
|
const categories = [
|
|
976
1034
|
createCategory("web-i18n", "Long Labels", [
|
|
977
|
-
createOption("web-i18n-next-intl"
|
|
978
|
-
createOption("web-i18n-react-intl"
|
|
1035
|
+
createOption("web-i18n-next-intl"),
|
|
1036
|
+
createOption("web-i18n-react-intl")
|
|
979
1037
|
])
|
|
980
1038
|
];
|
|
981
1039
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
982
1040
|
cleanup = unmount;
|
|
983
1041
|
const output = lastFrame();
|
|
984
|
-
globalExpect(output).toContain("
|
|
1042
|
+
globalExpect(output).toContain("Next Intl");
|
|
985
1043
|
});
|
|
986
1044
|
it("should handle categories with different option counts", () => {
|
|
987
1045
|
const categories = [
|
|
988
1046
|
createCategory("web-framework", "Category 1", [
|
|
989
|
-
createOption("web-forms-react-hook-form"
|
|
990
|
-
createOption("web-forms-vee-validate"
|
|
991
|
-
]),
|
|
992
|
-
createCategory("web-styling", "Category 2", [
|
|
993
|
-
createOption("web-forms-zod-validation", "Option 3")
|
|
1047
|
+
createOption("web-forms-react-hook-form"),
|
|
1048
|
+
createOption("web-forms-vee-validate")
|
|
994
1049
|
]),
|
|
1050
|
+
createCategory("web-styling", "Category 2", [createOption("web-forms-zod-validation")]),
|
|
995
1051
|
createCategory("web-client-state", "Category 3", [
|
|
996
|
-
createOption("web-testing-vitest"
|
|
997
|
-
createOption("web-testing-playwright-e2e"
|
|
998
|
-
createOption("web-testing-react-testing-library"
|
|
1052
|
+
createOption("web-testing-vitest"),
|
|
1053
|
+
createOption("web-testing-playwright-e2e"),
|
|
1054
|
+
createOption("web-testing-react-testing-library")
|
|
999
1055
|
])
|
|
1000
1056
|
];
|
|
1001
1057
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
@@ -1014,16 +1070,14 @@ describe("CategoryGrid component", () => {
|
|
|
1014
1070
|
"web-framework",
|
|
1015
1071
|
"Framework",
|
|
1016
1072
|
[
|
|
1017
|
-
createOption("web-forms-react-hook-form",
|
|
1073
|
+
createOption("web-forms-react-hook-form", { selected: true }),
|
|
1018
1074
|
// Framework selected
|
|
1019
|
-
createOption("web-forms-vee-validate"
|
|
1020
|
-
createOption("web-forms-zod-validation"
|
|
1075
|
+
createOption("web-forms-vee-validate"),
|
|
1076
|
+
createOption("web-forms-zod-validation")
|
|
1021
1077
|
],
|
|
1022
1078
|
{ required: true }
|
|
1023
1079
|
),
|
|
1024
|
-
createCategory("web-styling", "Category 2", [
|
|
1025
|
-
createOption("web-testing-vitest", "Option 4")
|
|
1026
|
-
])
|
|
1080
|
+
createCategory("web-styling", "Category 2", [createOption("web-testing-vitest")])
|
|
1027
1081
|
];
|
|
1028
1082
|
const { stdin, unmount } = renderGrid({
|
|
1029
1083
|
categories,
|
|
@@ -1040,22 +1094,22 @@ describe("CategoryGrid component", () => {
|
|
|
1040
1094
|
});
|
|
1041
1095
|
});
|
|
1042
1096
|
describe("installed skills", () => {
|
|
1043
|
-
it("should render installed skill with
|
|
1097
|
+
it("should render installed skill with display name (no checkmark icon)", () => {
|
|
1044
1098
|
const categories = [
|
|
1045
1099
|
createCategory("web-forms", "Forms", [
|
|
1046
|
-
createOption("web-forms-react-hook-form",
|
|
1100
|
+
createOption("web-forms-react-hook-form", { installed: true })
|
|
1047
1101
|
])
|
|
1048
1102
|
];
|
|
1049
1103
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
1050
1104
|
cleanup = unmount;
|
|
1051
1105
|
const output = lastFrame();
|
|
1052
1106
|
globalExpect(output).not.toContain("\u2713");
|
|
1053
|
-
globalExpect(output).toContain("
|
|
1107
|
+
globalExpect(output).toContain("React Hook Form");
|
|
1054
1108
|
});
|
|
1055
|
-
it("should render installed and selected skill with
|
|
1109
|
+
it("should render installed and selected skill with display name only", () => {
|
|
1056
1110
|
const categories = [
|
|
1057
1111
|
createCategory("web-forms", "Forms", [
|
|
1058
|
-
createOption("web-forms-react-hook-form",
|
|
1112
|
+
createOption("web-forms-react-hook-form", {
|
|
1059
1113
|
installed: true,
|
|
1060
1114
|
selected: true
|
|
1061
1115
|
})
|
|
@@ -1065,19 +1119,19 @@ describe("CategoryGrid component", () => {
|
|
|
1065
1119
|
cleanup = unmount;
|
|
1066
1120
|
const output = lastFrame();
|
|
1067
1121
|
globalExpect(output).not.toContain("\u2713");
|
|
1068
|
-
globalExpect(output).toContain("
|
|
1122
|
+
globalExpect(output).toContain("React Hook Form");
|
|
1069
1123
|
});
|
|
1070
1124
|
it("should render local installed skill without L badge or checkmark", () => {
|
|
1071
1125
|
const categories = [
|
|
1072
1126
|
createCategory("web-forms", "Forms", [
|
|
1073
|
-
createOption("web-forms-react-hook-form",
|
|
1127
|
+
createOption("web-forms-react-hook-form", { local: true, installed: true })
|
|
1074
1128
|
])
|
|
1075
1129
|
];
|
|
1076
1130
|
const { lastFrame, unmount } = renderGrid({ categories });
|
|
1077
1131
|
cleanup = unmount;
|
|
1078
1132
|
const output = lastFrame();
|
|
1079
1133
|
globalExpect(output).not.toContain("\u2713");
|
|
1080
|
-
globalExpect(output).toContain("
|
|
1134
|
+
globalExpect(output).toContain("React Hook Form");
|
|
1081
1135
|
});
|
|
1082
1136
|
});
|
|
1083
1137
|
describe("natural flow (no virtual scroll)", () => {
|
|
@@ -1128,10 +1182,7 @@ describe("CategoryGrid component", () => {
|
|
|
1128
1182
|
createCategory(
|
|
1129
1183
|
"web-framework",
|
|
1130
1184
|
"Framework",
|
|
1131
|
-
[
|
|
1132
|
-
createOption("web-framework-react", "React"),
|
|
1133
|
-
createOption("web-framework-vue-composition-api", "Vue")
|
|
1134
|
-
],
|
|
1185
|
+
[createOption("web-framework-react"), createOption("web-framework-vue-composition-api")],
|
|
1135
1186
|
{ exclusive: true }
|
|
1136
1187
|
)
|
|
1137
1188
|
];
|
|
@@ -1146,8 +1197,8 @@ describe("CategoryGrid component", () => {
|
|
|
1146
1197
|
"web-framework",
|
|
1147
1198
|
"Framework",
|
|
1148
1199
|
[
|
|
1149
|
-
createOption("web-framework-react",
|
|
1150
|
-
createOption("web-framework-vue-composition-api"
|
|
1200
|
+
createOption("web-framework-react", { selected: true }),
|
|
1201
|
+
createOption("web-framework-vue-composition-api")
|
|
1151
1202
|
],
|
|
1152
1203
|
{ exclusive: true }
|
|
1153
1204
|
)
|
|
@@ -1163,9 +1214,9 @@ describe("CategoryGrid component", () => {
|
|
|
1163
1214
|
"web-testing",
|
|
1164
1215
|
"Testing",
|
|
1165
1216
|
[
|
|
1166
|
-
createOption("web-testing-vitest",
|
|
1167
|
-
createOption("web-testing-playwright-e2e",
|
|
1168
|
-
createOption("web-testing-cypress-e2e"
|
|
1217
|
+
createOption("web-testing-vitest", { selected: true }),
|
|
1218
|
+
createOption("web-testing-playwright-e2e", { selected: true }),
|
|
1219
|
+
createOption("web-testing-cypress-e2e")
|
|
1169
1220
|
],
|
|
1170
1221
|
{ exclusive: false }
|
|
1171
1222
|
)
|
|
@@ -1180,10 +1231,7 @@ describe("CategoryGrid component", () => {
|
|
|
1180
1231
|
createCategory(
|
|
1181
1232
|
"web-testing",
|
|
1182
1233
|
"Testing",
|
|
1183
|
-
[
|
|
1184
|
-
createOption("web-testing-vitest", "Vitest"),
|
|
1185
|
-
createOption("web-testing-playwright-e2e", "Playwright")
|
|
1186
|
-
],
|
|
1234
|
+
[createOption("web-testing-vitest"), createOption("web-testing-playwright-e2e")],
|
|
1187
1235
|
{ exclusive: false }
|
|
1188
1236
|
)
|
|
1189
1237
|
];
|
|
@@ -1197,13 +1245,13 @@ describe("CategoryGrid component", () => {
|
|
|
1197
1245
|
createCategory(
|
|
1198
1246
|
"web-framework",
|
|
1199
1247
|
"Framework",
|
|
1200
|
-
[createOption("web-framework-react",
|
|
1248
|
+
[createOption("web-framework-react", { selected: true })],
|
|
1201
1249
|
{ exclusive: true }
|
|
1202
1250
|
),
|
|
1203
1251
|
createCategory(
|
|
1204
1252
|
"web-testing",
|
|
1205
1253
|
"Testing",
|
|
1206
|
-
[createOption("web-testing-vitest",
|
|
1254
|
+
[createOption("web-testing-vitest", { selected: true })],
|
|
1207
1255
|
{ exclusive: false }
|
|
1208
1256
|
)
|
|
1209
1257
|
];
|
|
@@ -1219,8 +1267,8 @@ describe("CategoryGrid component", () => {
|
|
|
1219
1267
|
"web-framework",
|
|
1220
1268
|
"Framework",
|
|
1221
1269
|
[
|
|
1222
|
-
createOption("web-framework-react",
|
|
1223
|
-
createOption("web-framework-vue-composition-api"
|
|
1270
|
+
createOption("web-framework-react", { selected: true }),
|
|
1271
|
+
createOption("web-framework-vue-composition-api")
|
|
1224
1272
|
],
|
|
1225
1273
|
{ exclusive: true }
|
|
1226
1274
|
),
|
|
@@ -1228,9 +1276,9 @@ describe("CategoryGrid component", () => {
|
|
|
1228
1276
|
"web-testing",
|
|
1229
1277
|
"Testing",
|
|
1230
1278
|
[
|
|
1231
|
-
createOption("web-testing-vitest",
|
|
1232
|
-
createOption("web-testing-playwright-e2e",
|
|
1233
|
-
createOption("web-testing-cypress-e2e"
|
|
1279
|
+
createOption("web-testing-vitest", { selected: true }),
|
|
1280
|
+
createOption("web-testing-playwright-e2e", { selected: true }),
|
|
1281
|
+
createOption("web-testing-cypress-e2e")
|
|
1234
1282
|
],
|
|
1235
1283
|
{ exclusive: false }
|
|
1236
1284
|
)
|