odac 0.9.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/.editorconfig +21 -0
- package/.github/workflows/auto-pr-description.yml +49 -0
- package/.github/workflows/release.yml +32 -0
- package/.github/workflows/test-coverage.yml +58 -0
- package/.husky/pre-commit +2 -0
- package/.kiro/steering/code-style.md +56 -0
- package/.kiro/steering/product.md +20 -0
- package/.kiro/steering/structure.md +77 -0
- package/.kiro/steering/tech.md +87 -0
- package/.prettierrc +10 -0
- package/.releaserc.js +134 -0
- package/AGENTS.md +84 -0
- package/CHANGELOG.md +181 -0
- package/CODE_OF_CONDUCT.md +83 -0
- package/CONTRIBUTING.md +63 -0
- package/LICENSE +661 -0
- package/README.md +57 -0
- package/SECURITY.md +26 -0
- package/bin/candy +10 -0
- package/bin/candypack +10 -0
- package/cli/index.js +3 -0
- package/cli/src/Cli.js +348 -0
- package/cli/src/Connector.js +93 -0
- package/cli/src/Monitor.js +416 -0
- package/core/Candy.js +87 -0
- package/core/Commands.js +239 -0
- package/core/Config.js +1094 -0
- package/core/Lang.js +52 -0
- package/core/Log.js +43 -0
- package/core/Process.js +26 -0
- package/docs/backend/01-overview/01-whats-in-the-candy-box.md +9 -0
- package/docs/backend/01-overview/02-super-handy-helper-functions.md +9 -0
- package/docs/backend/01-overview/03-development-server.md +79 -0
- package/docs/backend/02-structure/01-typical-project-layout.md +39 -0
- package/docs/backend/03-config/00-configuration-overview.md +214 -0
- package/docs/backend/03-config/01-database-connection.md +60 -0
- package/docs/backend/03-config/02-static-route-mapping-optional.md +20 -0
- package/docs/backend/03-config/03-request-timeout.md +11 -0
- package/docs/backend/03-config/04-environment-variables.md +227 -0
- package/docs/backend/03-config/05-early-hints.md +352 -0
- package/docs/backend/04-routing/01-basic-page-routes.md +28 -0
- package/docs/backend/04-routing/02-controller-less-view-routes.md +43 -0
- package/docs/backend/04-routing/03-api-and-data-routes.md +20 -0
- package/docs/backend/04-routing/04-authentication-aware-routes.md +48 -0
- package/docs/backend/04-routing/05-advanced-routing.md +14 -0
- package/docs/backend/04-routing/06-error-pages.md +101 -0
- package/docs/backend/04-routing/07-cron-jobs.md +149 -0
- package/docs/backend/05-controllers/01-how-to-build-a-controller.md +17 -0
- package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +20 -0
- package/docs/backend/05-controllers/03-controller-classes.md +93 -0
- package/docs/backend/05-forms/01-custom-forms.md +395 -0
- package/docs/backend/05-forms/02-automatic-database-insert.md +297 -0
- package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +96 -0
- package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +40 -0
- package/docs/backend/07-views/01-the-view-directory.md +73 -0
- package/docs/backend/07-views/02-rendering-a-view.md +179 -0
- package/docs/backend/07-views/03-template-syntax.md +181 -0
- package/docs/backend/07-views/03-variables.md +328 -0
- package/docs/backend/07-views/04-request-data.md +231 -0
- package/docs/backend/07-views/05-conditionals.md +290 -0
- package/docs/backend/07-views/06-loops.md +353 -0
- package/docs/backend/07-views/07-translations.md +358 -0
- package/docs/backend/07-views/08-backend-javascript.md +398 -0
- package/docs/backend/07-views/09-comments.md +297 -0
- package/docs/backend/08-database/01-database-connection.md +99 -0
- package/docs/backend/08-database/02-using-mysql.md +322 -0
- package/docs/backend/09-validation/01-the-validator-service.md +424 -0
- package/docs/backend/10-authentication/01-user-logins-with-authjs.md +53 -0
- package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +55 -0
- package/docs/backend/10-authentication/03-register.md +134 -0
- package/docs/backend/10-authentication/04-candy-register-forms.md +676 -0
- package/docs/backend/10-authentication/05-session-management.md +159 -0
- package/docs/backend/10-authentication/06-candy-login-forms.md +596 -0
- package/docs/backend/11-mail/01-the-mail-service.md +42 -0
- package/docs/backend/12-streaming/01-streaming-overview.md +300 -0
- package/docs/backend/13-utilities/01-candy-var.md +504 -0
- package/docs/frontend/01-overview/01-introduction.md +146 -0
- package/docs/frontend/02-ajax-navigation/01-quick-start.md +608 -0
- package/docs/frontend/02-ajax-navigation/02-configuration.md +370 -0
- package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +519 -0
- package/docs/frontend/03-forms/01-form-handling.md +420 -0
- package/docs/frontend/04-api-requests/01-get-post.md +443 -0
- package/docs/frontend/05-streaming/01-client-streaming.md +163 -0
- package/docs/index.json +452 -0
- package/docs/server/01-installation/01-quick-install.md +19 -0
- package/docs/server/01-installation/02-manual-installation-via-npm.md +9 -0
- package/docs/server/02-get-started/01-core-concepts.md +7 -0
- package/docs/server/02-get-started/02-basic-commands.md +57 -0
- package/docs/server/02-get-started/03-cli-reference.md +276 -0
- package/docs/server/02-get-started/04-cli-quick-reference.md +102 -0
- package/docs/server/03-service/01-start-a-new-service.md +57 -0
- package/docs/server/03-service/02-delete-a-service.md +48 -0
- package/docs/server/04-web/01-create-a-website.md +36 -0
- package/docs/server/04-web/02-list-websites.md +9 -0
- package/docs/server/04-web/03-delete-a-website.md +29 -0
- package/docs/server/05-subdomain/01-create-a-subdomain.md +32 -0
- package/docs/server/05-subdomain/02-list-subdomains.md +33 -0
- package/docs/server/05-subdomain/03-delete-a-subdomain.md +41 -0
- package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +34 -0
- package/docs/server/07-mail/01-create-a-mail-account.md +23 -0
- package/docs/server/07-mail/02-delete-a-mail-account.md +20 -0
- package/docs/server/07-mail/03-list-mail-accounts.md +20 -0
- package/docs/server/07-mail/04-change-account-password.md +23 -0
- package/eslint.config.mjs +120 -0
- package/framework/index.js +4 -0
- package/framework/src/Auth.js +309 -0
- package/framework/src/Candy.js +81 -0
- package/framework/src/Config.js +79 -0
- package/framework/src/Env.js +60 -0
- package/framework/src/Lang.js +57 -0
- package/framework/src/Mail.js +83 -0
- package/framework/src/Mysql.js +575 -0
- package/framework/src/Request.js +301 -0
- package/framework/src/Route/Cron.js +128 -0
- package/framework/src/Route/Internal.js +439 -0
- package/framework/src/Route.js +455 -0
- package/framework/src/Server.js +15 -0
- package/framework/src/Stream.js +163 -0
- package/framework/src/Token.js +37 -0
- package/framework/src/Validator.js +271 -0
- package/framework/src/Var.js +211 -0
- package/framework/src/View/EarlyHints.js +190 -0
- package/framework/src/View/Form.js +600 -0
- package/framework/src/View.js +513 -0
- package/framework/web/candy.js +838 -0
- package/jest.config.js +22 -0
- package/locale/de-DE.json +80 -0
- package/locale/en-US.json +79 -0
- package/locale/es-ES.json +80 -0
- package/locale/fr-FR.json +80 -0
- package/locale/pt-BR.json +80 -0
- package/locale/ru-RU.json +80 -0
- package/locale/tr-TR.json +85 -0
- package/locale/zh-CN.json +80 -0
- package/package.json +86 -0
- package/server/index.js +5 -0
- package/server/src/Api.js +88 -0
- package/server/src/DNS.js +940 -0
- package/server/src/Hub.js +535 -0
- package/server/src/Mail.js +571 -0
- package/server/src/SSL.js +180 -0
- package/server/src/Server.js +27 -0
- package/server/src/Service.js +248 -0
- package/server/src/Subdomain.js +64 -0
- package/server/src/Web/Firewall.js +170 -0
- package/server/src/Web/Proxy.js +134 -0
- package/server/src/Web.js +451 -0
- package/server/src/mail/imap.js +1091 -0
- package/server/src/mail/server.js +32 -0
- package/server/src/mail/smtp.js +786 -0
- package/test/cli/Cli.test.js +36 -0
- package/test/core/Candy.test.js +234 -0
- package/test/core/Commands.test.js +538 -0
- package/test/core/Config.test.js +1435 -0
- package/test/core/Lang.test.js +250 -0
- package/test/core/Process.test.js +156 -0
- package/test/framework/Route.test.js +239 -0
- package/test/framework/View/EarlyHints.test.js +282 -0
- package/test/scripts/check-coverage.js +132 -0
- package/test/server/Api.test.js +647 -0
- package/test/server/Client.test.js +338 -0
- package/test/server/DNS.test.js +2050 -0
- package/test/server/DNS.test.js.bak +2084 -0
- package/test/server/Log.test.js +73 -0
- package/test/server/Mail.account.test_.js +460 -0
- package/test/server/Mail.init.test_.js +411 -0
- package/test/server/Mail.test_.js +1340 -0
- package/test/server/SSL.test_.js +1491 -0
- package/test/server/Server.test.js +765 -0
- package/test/server/Service.test_.js +1127 -0
- package/test/server/Subdomain.test.js +440 -0
- package/test/server/Web/Firewall.test.js +175 -0
- package/test/server/Web.test_.js +1562 -0
- package/test/server/__mocks__/acme-client.js +17 -0
- package/test/server/__mocks__/bcrypt.js +50 -0
- package/test/server/__mocks__/child_process.js +389 -0
- package/test/server/__mocks__/crypto.js +432 -0
- package/test/server/__mocks__/fs.js +450 -0
- package/test/server/__mocks__/globalCandy.js +227 -0
- package/test/server/__mocks__/http-proxy.js +105 -0
- package/test/server/__mocks__/http.js +575 -0
- package/test/server/__mocks__/https.js +272 -0
- package/test/server/__mocks__/index.js +249 -0
- package/test/server/__mocks__/mail/server.js +100 -0
- package/test/server/__mocks__/mail/smtp.js +31 -0
- package/test/server/__mocks__/mailparser.js +81 -0
- package/test/server/__mocks__/net.js +369 -0
- package/test/server/__mocks__/node-forge.js +328 -0
- package/test/server/__mocks__/os.js +320 -0
- package/test/server/__mocks__/path.js +291 -0
- package/test/server/__mocks__/selfsigned.js +8 -0
- package/test/server/__mocks__/server/src/mail/server.js +100 -0
- package/test/server/__mocks__/server/src/mail/smtp.js +31 -0
- package/test/server/__mocks__/smtp-server.js +106 -0
- package/test/server/__mocks__/sqlite3.js +394 -0
- package/test/server/__mocks__/testFactories.js +299 -0
- package/test/server/__mocks__/testHelpers.js +363 -0
- package/test/server/__mocks__/tls.js +229 -0
- package/watchdog/index.js +3 -0
- package/watchdog/src/Watchdog.js +156 -0
- package/web/config.json +5 -0
- package/web/controller/page/about.js +27 -0
- package/web/controller/page/index.js +34 -0
- package/web/package.json +18 -0
- package/web/public/assets/css/style.css +1835 -0
- package/web/public/assets/js/app.js +96 -0
- package/web/route/www.js +19 -0
- package/web/skeleton/main.html +22 -0
- package/web/view/content/about.html +65 -0
- package/web/view/content/home.html +205 -0
- package/web/view/footer/main.html +11 -0
- package/web/view/head/main.html +5 -0
- package/web/view/header/main.html +14 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const Cli = require('../../cli/src/Cli.js')
|
|
2
|
+
|
|
3
|
+
describe('CLI Prefix Argument Parsing', () => {
|
|
4
|
+
test('parseArg should extract value after prefix', () => {
|
|
5
|
+
const args = ['web', 'create', '-d', 'example.com', '--other', 'value']
|
|
6
|
+
|
|
7
|
+
expect(Cli.parseArg(args, ['-d', '--domain'])).toBe('example.com')
|
|
8
|
+
expect(Cli.parseArg(args, ['--other'])).toBe('value')
|
|
9
|
+
expect(Cli.parseArg(args, ['-x', '--missing'])).toBeNull()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('parseArg should handle multiple prefix options', () => {
|
|
13
|
+
const args = ['mail', 'create', '--email', 'test@example.com', '-p', 'password123']
|
|
14
|
+
|
|
15
|
+
expect(Cli.parseArg(args, ['-e', '--email'])).toBe('test@example.com')
|
|
16
|
+
expect(Cli.parseArg(args, ['-p', '--password'])).toBe('password123')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('parseArg should return null for missing arguments', () => {
|
|
20
|
+
const args = ['web', 'create']
|
|
21
|
+
|
|
22
|
+
expect(Cli.parseArg(args, ['-d', '--domain'])).toBeNull()
|
|
23
|
+
expect(Cli.parseArg(null, ['-d'])).toBeNull()
|
|
24
|
+
expect(Cli.parseArg(args, null)).toBeNull()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('parseArg should handle edge cases', () => {
|
|
28
|
+
const args = ['command', '-d']
|
|
29
|
+
|
|
30
|
+
// Missing value after prefix
|
|
31
|
+
expect(Cli.parseArg(args, ['-d'])).toBeNull()
|
|
32
|
+
|
|
33
|
+
// Empty args
|
|
34
|
+
expect(Cli.parseArg([], ['-d'])).toBeNull()
|
|
35
|
+
})
|
|
36
|
+
})
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
// Mock fs before requiring any modules that might use it
|
|
2
|
+
jest.mock('fs', () => ({
|
|
3
|
+
promises: {
|
|
4
|
+
writeFile: jest.fn().mockResolvedValue()
|
|
5
|
+
},
|
|
6
|
+
readFileSync: jest.fn().mockReturnValue('{"Status": "Status"}'),
|
|
7
|
+
writeFileSync: jest.fn(),
|
|
8
|
+
existsSync: jest.fn().mockReturnValue(true),
|
|
9
|
+
mkdirSync: jest.fn()
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
// Mock process.mainModule to avoid Config initialization issues
|
|
13
|
+
process.mainModule = {path: '/mock/node_modules/candypack/bin'}
|
|
14
|
+
|
|
15
|
+
// Import the module to ensure global setup
|
|
16
|
+
require('../../core/Candy.js')
|
|
17
|
+
|
|
18
|
+
describe('CandyPack', () => {
|
|
19
|
+
describe('global setup', () => {
|
|
20
|
+
it('should have global Candy instance', () => {
|
|
21
|
+
expect(global.Candy).toBeDefined()
|
|
22
|
+
expect(global.Candy._registry).toBeInstanceOf(Map)
|
|
23
|
+
expect(global.Candy._singletons).toBeInstanceOf(Map)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should have global __ function', () => {
|
|
27
|
+
expect(global.__).toBeDefined()
|
|
28
|
+
expect(typeof global.__).toBe('function')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('should call Lang.get through global __ function', () => {
|
|
32
|
+
const result = global.__('Status')
|
|
33
|
+
expect(result).toBe('Status')
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should not recreate global if already exists', () => {
|
|
37
|
+
const existingCandy = global.Candy
|
|
38
|
+
|
|
39
|
+
// Clear module cache and re-require
|
|
40
|
+
delete require.cache[require.resolve('../../core/Candy.js')]
|
|
41
|
+
require('../../core/Candy.js')
|
|
42
|
+
|
|
43
|
+
expect(global.Candy).toBe(existingCandy)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('CandyPack instance methods', () => {
|
|
48
|
+
it('should have core method', () => {
|
|
49
|
+
expect(typeof global.Candy.core).toBe('function')
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should have cli method', () => {
|
|
53
|
+
expect(typeof global.Candy.cli).toBe('function')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should have server method', () => {
|
|
57
|
+
expect(typeof global.Candy.server).toBe('function')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('should have watchdog method', () => {
|
|
61
|
+
expect(typeof global.Candy.watchdog).toBe('function')
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe('module loading functionality', () => {
|
|
66
|
+
it('should load core modules', () => {
|
|
67
|
+
const lang = global.Candy.core('Lang')
|
|
68
|
+
expect(lang).toBeDefined()
|
|
69
|
+
expect(global.Candy._registry.has('core:Lang')).toBe(true)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should return singleton instances by default', () => {
|
|
73
|
+
const lang1 = global.Candy.core('Lang')
|
|
74
|
+
const lang2 = global.Candy.core('Lang')
|
|
75
|
+
expect(lang1).toBe(lang2)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('should cache singleton instances', () => {
|
|
79
|
+
const lang1 = global.Candy.core('Lang')
|
|
80
|
+
const lang2 = global.Candy.core('Lang')
|
|
81
|
+
|
|
82
|
+
expect(lang1).toBe(lang2)
|
|
83
|
+
expect(global.Candy._singletons.has('core:Lang')).toBe(true)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('should return new instances when singleton is false', () => {
|
|
87
|
+
// Clear any existing Lang registration first to test non-singleton behavior
|
|
88
|
+
global.Candy._registry.delete('core:Lang')
|
|
89
|
+
global.Candy._singletons.delete('core:Lang')
|
|
90
|
+
|
|
91
|
+
const lang1 = global.Candy.core('Lang', false)
|
|
92
|
+
const lang2 = global.Candy.core('Lang', false)
|
|
93
|
+
expect(lang1).not.toBe(lang2)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should call init method if module has one', () => {
|
|
97
|
+
// Test with Config module which has init method
|
|
98
|
+
const config = global.Candy.core('Config')
|
|
99
|
+
expect(config).toBeDefined()
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('should retrieve Config module as singleton', () => {
|
|
103
|
+
// Get Config instance twice
|
|
104
|
+
const config1 = global.Candy.core('Config')
|
|
105
|
+
const config2 = global.Candy.core('Config')
|
|
106
|
+
|
|
107
|
+
// Should be the same instance (singleton behavior)
|
|
108
|
+
expect(config1).toBe(config2)
|
|
109
|
+
expect(config1).toBeInstanceOf(Object)
|
|
110
|
+
|
|
111
|
+
// Should be registered in singleton cache
|
|
112
|
+
expect(global.Candy._singletons.has('core:Config')).toBe(true)
|
|
113
|
+
expect(global.Candy._singletons.get('core:Config')).toBe(config1)
|
|
114
|
+
|
|
115
|
+
// Should have Config class properties
|
|
116
|
+
expect(config1.config).toBeDefined()
|
|
117
|
+
expect(typeof config1.force).toBe('function')
|
|
118
|
+
expect(typeof config1.reload).toBe('function')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should handle modules without init method', () => {
|
|
122
|
+
// Test with Process module which doesn't have init method
|
|
123
|
+
const process = global.Candy.core('Process')
|
|
124
|
+
expect(process).toBeDefined()
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe('different module types', () => {
|
|
129
|
+
it('should load cli modules with correct path prefix', () => {
|
|
130
|
+
// This will fail but we can test the path construction
|
|
131
|
+
expect(() => {
|
|
132
|
+
global.Candy.cli('NonExistentCli')
|
|
133
|
+
}).toThrow()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('should load server modules with correct path prefix', () => {
|
|
137
|
+
// This will fail but we can test the path construction
|
|
138
|
+
expect(() => {
|
|
139
|
+
global.Candy.server('NonExistentServer')
|
|
140
|
+
}).toThrow()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('should load watchdog modules with correct path prefix', () => {
|
|
144
|
+
// This will fail but we can test the path construction
|
|
145
|
+
expect(() => {
|
|
146
|
+
global.Candy.watchdog('NonExistentWatchdog')
|
|
147
|
+
}).toThrow()
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
describe('registry functionality', () => {
|
|
152
|
+
it('should maintain separate registries for different module types', () => {
|
|
153
|
+
// Load a core module
|
|
154
|
+
global.Candy.core('Lang')
|
|
155
|
+
|
|
156
|
+
expect(global.Candy._registry.has('core:Lang')).toBe(true)
|
|
157
|
+
expect(global.Candy._registry.size).toBeGreaterThan(0)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('should store registry entries with correct structure', () => {
|
|
161
|
+
global.Candy.core('Lang')
|
|
162
|
+
|
|
163
|
+
const entry = global.Candy._registry.get('core:Lang')
|
|
164
|
+
expect(entry).toBeDefined()
|
|
165
|
+
expect(entry).toHaveProperty('value')
|
|
166
|
+
expect(entry).toHaveProperty('singleton')
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should handle non-singleton registry entries', () => {
|
|
170
|
+
// Clear existing registration
|
|
171
|
+
global.Candy._registry.delete('core:Lang')
|
|
172
|
+
global.Candy._singletons.delete('core:Lang')
|
|
173
|
+
|
|
174
|
+
global.Candy.core('Lang', false)
|
|
175
|
+
|
|
176
|
+
const entry = global.Candy._registry.get('core:Lang')
|
|
177
|
+
expect(entry.singleton).toBe(false)
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('instantiation behavior', () => {
|
|
182
|
+
it('should instantiate function modules', () => {
|
|
183
|
+
const lang = global.Candy.core('Lang')
|
|
184
|
+
expect(lang).toBeInstanceOf(Object)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('should handle non-function modules', () => {
|
|
188
|
+
const config = global.Candy.core('Config')
|
|
189
|
+
expect(config).toBeDefined()
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
describe('error handling', () => {
|
|
194
|
+
it('should handle module loading errors gracefully', () => {
|
|
195
|
+
expect(() => {
|
|
196
|
+
global.Candy.core('NonExistentModule')
|
|
197
|
+
}).toThrow()
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('should throw specific error for non-existent registry entries', () => {
|
|
201
|
+
// Create a new CandyPack instance to test private methods
|
|
202
|
+
const CandyPackClass = global.Candy.constructor
|
|
203
|
+
const testInstance = new CandyPackClass()
|
|
204
|
+
|
|
205
|
+
expect(() => {
|
|
206
|
+
// This should trigger the resolve error
|
|
207
|
+
testInstance.core('NonExistentModule')
|
|
208
|
+
}).toThrow()
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
describe('module caching', () => {
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
// Clear any existing registrations for clean tests
|
|
215
|
+
global.Candy._registry.clear()
|
|
216
|
+
global.Candy._singletons.clear()
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
it('should not re-register already registered modules', () => {
|
|
220
|
+
// Load Lang module twice
|
|
221
|
+
const lang1 = global.Candy.core('Lang')
|
|
222
|
+
const lang2 = global.Candy.core('Lang')
|
|
223
|
+
|
|
224
|
+
expect(lang1).toBe(lang2)
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it('should maintain singleton cache correctly', () => {
|
|
228
|
+
const lang = global.Candy.core('Lang')
|
|
229
|
+
|
|
230
|
+
expect(global.Candy._singletons.has('core:Lang')).toBe(true)
|
|
231
|
+
expect(global.Candy._singletons.get('core:Lang')).toBe(lang)
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
})
|