@stone-js/starters 0.8.8 → 0.8.10

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 (101) hide show
  1. package/README.md +2 -2
  2. package/basic-react-declarative/app/Application.tsx +0 -2
  3. package/basic-react-declarative/package.json +7 -7
  4. package/basic-react-declarative/public/favicon.svg +16 -0
  5. package/basic-react-declarative/tests/Application.spec.ts +25 -100
  6. package/basic-react-imperative/app/Application.tsx +2 -17
  7. package/basic-react-imperative/package.json +7 -7
  8. package/basic-react-imperative/public/favicon.svg +16 -0
  9. package/basic-react-imperative/tests/Application.spec.ts +25 -86
  10. package/basic-react-native-declarative/App.tsx +192 -0
  11. package/basic-react-native-declarative/LICENSE +21 -0
  12. package/basic-react-native-declarative/README.md +35 -0
  13. package/basic-react-native-declarative/adapter/NativeAdapter.ts +108 -0
  14. package/basic-react-native-declarative/adapter/NativeErrorHandler.ts +53 -0
  15. package/basic-react-native-declarative/adapter/NativeEventSource.ts +58 -0
  16. package/basic-react-native-declarative/adapter/RawResponseWrapper.ts +30 -0
  17. package/basic-react-native-declarative/adapter/declarations.ts +40 -0
  18. package/basic-react-native-declarative/adapter/middleware.ts +73 -0
  19. package/basic-react-native-declarative/adapter/nativeAdapterBlueprint.ts +51 -0
  20. package/basic-react-native-declarative/adapter/renderSink.ts +52 -0
  21. package/basic-react-native-declarative/app/Application.ts +17 -0
  22. package/basic-react-native-declarative/app/WelcomeController.ts +66 -0
  23. package/basic-react-native-declarative/app.json +25 -0
  24. package/basic-react-native-declarative/assets/android-icon-background.png +0 -0
  25. package/basic-react-native-declarative/assets/android-icon-foreground.png +0 -0
  26. package/basic-react-native-declarative/assets/android-icon-monochrome.png +0 -0
  27. package/basic-react-native-declarative/assets/favicon.png +0 -0
  28. package/basic-react-native-declarative/assets/icon.png +0 -0
  29. package/basic-react-native-declarative/assets/splash-icon.png +0 -0
  30. package/basic-react-native-declarative/babel.config.js +16 -0
  31. package/basic-react-native-declarative/index.ts +22 -0
  32. package/basic-react-native-declarative/metro.config.js +7 -0
  33. package/basic-react-native-declarative/package.json +41 -0
  34. package/basic-react-native-declarative/tests/Application.spec.ts +65 -0
  35. package/basic-react-native-declarative/tsconfig.json +16 -0
  36. package/basic-react-native-declarative/vitest.config.ts +27 -0
  37. package/basic-service-declarative/app/Application.ts +0 -2
  38. package/basic-service-declarative/package.json +6 -6
  39. package/basic-service-declarative/tests/Application.spec.ts +20 -53
  40. package/basic-service-imperative/app/Application.ts +2 -14
  41. package/basic-service-imperative/package.json +6 -6
  42. package/basic-service-imperative/tests/Application.spec.ts +19 -44
  43. package/continuum-showcase/package.json +11 -10
  44. package/continuum-showcase/public/favicon.svg +16 -0
  45. package/continuum-showcase/stone.config.mjs +2 -2
  46. package/continuum-showcase/tests/application.spec.ts +30 -0
  47. package/full-react-declarative/app/Application.ts +0 -4
  48. package/full-react-declarative/package.json +12 -12
  49. package/full-react-declarative/public/favicon.svg +16 -0
  50. package/full-react-declarative/stone.config.mjs +2 -2
  51. package/full-react-declarative/tests/application.spec.ts +30 -0
  52. package/full-react-imperative/app/Application.ts +1 -3
  53. package/full-react-imperative/package.json +12 -12
  54. package/full-react-imperative/public/favicon.svg +16 -0
  55. package/full-react-imperative/stone.config.mjs +2 -2
  56. package/full-react-imperative/tests/application.spec.ts +30 -0
  57. package/full-service-declarative/app/Application.ts +5 -2
  58. package/full-service-declarative/app/configurations/AppConfiguration.ts +1 -3
  59. package/full-service-declarative/package.json +13 -12
  60. package/full-service-declarative/stone.config.mjs +2 -2
  61. package/full-service-declarative/tests/application.spec.ts +30 -0
  62. package/full-service-imperative/app/Application.ts +8 -2
  63. package/full-service-imperative/app/configurations/AppConfiguration.ts +1 -3
  64. package/full-service-imperative/package.json +13 -12
  65. package/full-service-imperative/stone.config.mjs +2 -2
  66. package/full-service-imperative/tests/application.spec.ts +30 -0
  67. package/package.json +15 -1
  68. package/standard-react-declarative/package.json +11 -10
  69. package/standard-react-declarative/public/favicon.svg +16 -0
  70. package/standard-react-declarative/tests/application.spec.ts +30 -0
  71. package/standard-react-imperative/package.json +11 -10
  72. package/standard-react-imperative/public/favicon.svg +16 -0
  73. package/standard-react-imperative/tests/application.spec.ts +30 -0
  74. package/standard-service-declarative/package.json +9 -8
  75. package/standard-service-declarative/tests/Application.spec.ts +22 -94
  76. package/standard-service-imperative/package.json +9 -8
  77. package/standard-service-imperative/tests/Application.spec.ts +22 -78
  78. package/basic-react-declarative/vitest.config.ts +0 -24
  79. package/basic-react-imperative/vitest.config.ts +0 -24
  80. package/basic-service-declarative/vitest.config.ts +0 -24
  81. package/basic-service-imperative/vitest.config.ts +0 -24
  82. package/continuum-showcase/tests/HomePage.spec.tsx +0 -41
  83. package/continuum-showcase/vitest.config.ts +0 -31
  84. package/full-react-declarative/tests/AppLayout.spec.ts +0 -51
  85. package/full-react-declarative/tests/HomePage.spec.ts +0 -38
  86. package/full-react-declarative/vitest.config.ts +0 -24
  87. package/full-react-imperative/tests/HomePage.spec.ts +0 -45
  88. package/full-react-imperative/tests/LayoutHeader.spec.ts +0 -39
  89. package/full-react-imperative/vitest.config.ts +0 -24
  90. package/full-service-declarative/tests/PostService.spec.ts +0 -56
  91. package/full-service-declarative/tests/WelcomeEventHandler.spec.ts +0 -54
  92. package/full-service-declarative/vitest.config.ts +0 -24
  93. package/full-service-imperative/tests/PostService.spec.ts +0 -47
  94. package/full-service-imperative/tests/WelcomeEventHandler.spec.ts +0 -31
  95. package/full-service-imperative/vitest.config.ts +0 -24
  96. package/standard-react-declarative/tests/WelcomePage.spec.ts +0 -71
  97. package/standard-react-declarative/vitest.config.ts +0 -24
  98. package/standard-react-imperative/tests/WelcomePage.spec.ts +0 -53
  99. package/standard-react-imperative/vitest.config.ts +0 -24
  100. package/standard-service-declarative/vitest.config.ts +0 -24
  101. package/standard-service-imperative/vitest.config.ts +0 -24
@@ -14,21 +14,22 @@
14
14
  "build": "stone build",
15
15
  "preview": "stone preview dist/server.mjs",
16
16
  "typings": "stone typings",
17
- "test": "vitest run",
18
- "test:cvg": "npm run test -- --coverage"
17
+ "test": "stone test",
18
+ "test:cvg": "stone test --coverage"
19
19
  },
20
20
  "dependencies": {
21
- "@stone-js/pipeline": "^0.8.8",
22
- "@stone-js/http-core": "^0.8.8",
23
- "@stone-js/node-http-adapter": "^0.8.8",
24
- "@stone-js/router": "^0.8.8",
25
- "@stone-js/core": "^0.8.8"
21
+ "@stone-js/pipeline": "^0.8.10",
22
+ "@stone-js/http-core": "^0.8.10",
23
+ "@stone-js/node-http-adapter": "^0.8.10",
24
+ "@stone-js/router": "^0.8.10",
25
+ "@stone-js/core": "^0.8.10"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@babel/plugin-proposal-decorators": "^7.25.9",
29
29
  "@babel/preset-env": "^7.26.9",
30
30
  "@babel/preset-typescript": "^7.27.0",
31
- "@stone-js/cli": "^0.8.8",
31
+ "@stone-js/cli": "^0.8.10",
32
+ "@stone-js/testing": "^0.8.10",
32
33
  "@types/node": "^24.0.7",
33
34
  "@vitest/coverage-v8": "^3.0.9",
34
35
  "vitest": "^3.0.9"
@@ -1,100 +1,28 @@
1
- import { ILogger } from '@stone-js/core'
2
- import { IncomingHttpEvent } from '@stone-js/http-core'
3
- import { WelcomeService } from '../app/services/WelcomeService'
4
- import { WelcomeEventHandler } from '../app/handlers/WelcomeEventHandler'
5
-
6
- // We must mock decorators to lighten the test environment
7
- vi.mock(import('@stone-js/core'), async (importOriginal) => {
8
- const actual = await importOriginal()
9
- return {
10
- ...actual,
11
- Service: vi.fn(() => vi.fn())
12
- }
13
- })
14
-
15
- // We must mock decorators to lighten the test environment
16
- vi.mock(import('@stone-js/router'), async (importOriginal) => {
17
- const actual = await importOriginal()
18
- return {
19
- ...actual,
20
- EventHandler: vi.fn(() => vi.fn()),
21
- Get: vi.fn(() => vi.fn())
22
- }
23
- })
24
-
25
- // We must mock decorators to lighten the test environment
26
- vi.mock(import('@stone-js/http-core'), async (importOriginal) => {
27
- const actual = await importOriginal()
28
- return {
29
- ...actual,
30
- JsonHttpResponse: vi.fn(() => vi.fn())
31
- }
32
- })
33
-
34
- describe('WelcomeService', () => {
35
- let mockedLogger: ILogger
36
- let service: WelcomeService
37
-
38
- beforeEach(() => {
39
- mockedLogger = {
40
- info: vi.fn()
41
- } as unknown as ILogger
42
-
43
- service = new WelcomeService({ logger: mockedLogger })
44
- })
45
-
46
- it('should build a branded welcome message for the given name', () => {
47
- // Act
48
- const response = service.welcome('Stone')
49
-
50
- // Assert
51
- expect(response.message).toBe('Hello Stone! Welcome to Stone.js.')
52
- expect(response.framework.name).toBe('Stone.js')
53
- expect(response.framework).toMatchObject({
54
- name: 'Stone.js',
55
- tagline: 'The continuum framework',
56
- docs: 'https://stonejs.dev',
57
- github: 'https://github.com/stone-foundation/stone-js-framework'
58
- })
59
- expect(mockedLogger.info).toHaveBeenCalledWith('Welcome Stone')
60
- })
61
- })
62
-
63
- describe('WelcomeEventHandler', () => {
64
- let mockedLogger: ILogger
65
- let handler: WelcomeEventHandler
66
-
67
- beforeEach(() => {
68
- mockedLogger = {
69
- info: vi.fn()
70
- } as unknown as ILogger
71
-
72
- handler = new WelcomeEventHandler({ welcomeService: new WelcomeService({ logger: mockedLogger }) })
73
- })
74
-
75
- it('should welcome the name carried by the event', () => {
76
- // Arrange
77
- const event = { get: () => 'World' } as unknown as IncomingHttpEvent
78
-
79
- // Act
80
- const response = handler.welcome(event)
81
-
82
- // Assert
83
- expect(response.message).toBe('Hello World! Welcome to Stone.js.')
84
- expect(response.framework.name).toBe('Stone.js')
85
- expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
1
+ import { createTestApp, makeIncomingHttpEvent } from '@stone-js/testing'
2
+
3
+ /**
4
+ * The whole application, booted in memory and asked a real question.
5
+ *
6
+ * Nothing is mocked and nothing is listed: `createTestApp()` discovers `app/**`, and the event goes
7
+ * through the same kernel production runs. If this passes the application works; if it fails the
8
+ * application is broken. That is the only kind of test worth shipping in a starter — the previous one
9
+ * stubbed out the framework's own decorators, which meant it could pass while nothing worked.
10
+ */
11
+ describe('Application', () => {
12
+ it('answers the caller', async () => {
13
+ const app = await createTestApp()
14
+
15
+ const response = await app.send(makeIncomingHttpEvent({ method: 'GET', url: '/?name=Ada' }))
16
+
17
+ expect(response.statusCode).toBe(200)
18
+ expect(response.json()).toMatchObject({ message: expect.stringContaining('Ada') })
86
19
  })
87
20
 
88
- it('should fall back to the default name when the event carries none', () => {
89
- // Arrange
90
- const event = { get: (_key: string, fallback: string) => fallback } as unknown as IncomingHttpEvent
21
+ it('answers when nobody says who they are', async () => {
22
+ const app = await createTestApp()
91
23
 
92
- // Act
93
- const response = handler.welcome(event)
24
+ const response = await app.send(makeIncomingHttpEvent({ method: 'GET', url: '/' }))
94
25
 
95
- // Assert
96
- expect(response.message).toBe('Hello World! Welcome to Stone.js.')
97
- expect(response.framework.name).toBe('Stone.js')
98
- expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
26
+ expect(response.statusCode).toBe(200)
99
27
  })
100
28
  })
@@ -13,21 +13,22 @@
13
13
  "build": "stone build",
14
14
  "preview": "stone preview dist/server.mjs",
15
15
  "typings": "stone typings",
16
- "test": "vitest run",
17
- "test:cvg": "npm run test -- --coverage"
16
+ "test": "stone test",
17
+ "test:cvg": "stone test --coverage"
18
18
  },
19
19
  "dependencies": {
20
- "@stone-js/pipeline": "^0.8.8",
21
- "@stone-js/http-core": "^0.8.8",
22
- "@stone-js/node-http-adapter": "^0.8.8",
23
- "@stone-js/router": "^0.8.8",
24
- "@stone-js/core": "^0.8.8"
20
+ "@stone-js/pipeline": "^0.8.10",
21
+ "@stone-js/http-core": "^0.8.10",
22
+ "@stone-js/node-http-adapter": "^0.8.10",
23
+ "@stone-js/router": "^0.8.10",
24
+ "@stone-js/core": "^0.8.10"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@babel/plugin-proposal-decorators": "^7.25.9",
28
28
  "@babel/preset-env": "^7.26.9",
29
29
  "@babel/preset-typescript": "^7.27.0",
30
- "@stone-js/cli": "^0.8.8",
30
+ "@stone-js/cli": "^0.8.10",
31
+ "@stone-js/testing": "^0.8.10",
31
32
  "@types/node": "^24.0.7",
32
33
  "@vitest/coverage-v8": "^3.0.9",
33
34
  "vitest": "^3.0.9"
@@ -1,84 +1,28 @@
1
- import { ILogger } from '@stone-js/core'
2
- import { IncomingHttpEvent } from '@stone-js/http-core'
3
- import { WelcomeService } from '../app/services/welcomeService'
4
- import { WelcomeEventHandler } from '../app/handlers/welcomeEventHandler'
5
-
6
- describe('WelcomeService', () => {
7
- let mockedLogger: ILogger
8
-
9
- beforeEach(() => {
10
- mockedLogger = {
11
- info: vi.fn()
12
- } as unknown as ILogger
13
- })
14
-
15
- it('should build a welcome message for the given name', () => {
16
- // Arrange
17
- const service = WelcomeService({ logger: mockedLogger })
18
-
19
- // Act
20
- const response = service.welcome('Stone')
21
-
22
- // Assert
23
- expect(response.message).toBe('Hello Stone! Welcome to Stone.js.')
24
- expect(response.framework.name).toBe('Stone.js')
25
- expect(response.framework).toMatchObject({
26
- name: 'Stone.js',
27
- tagline: 'The continuum framework',
28
- docs: 'https://stonejs.dev',
29
- github: 'https://github.com/stone-foundation/stone-js-framework'
30
- })
31
- expect(mockedLogger.info).toHaveBeenCalledWith('Welcome Stone')
32
- })
33
- })
34
-
35
- describe('WelcomeEventHandler', () => {
36
- let mockedLogger: ILogger
37
-
38
- beforeEach(() => {
39
- mockedLogger = {
40
- info: vi.fn()
41
- } as unknown as ILogger
42
- })
43
-
44
- it('should create a functional event handler', () => {
45
- // Arrange
46
- const welcomeService = WelcomeService({ logger: mockedLogger })
47
-
48
- // Act
49
- const handler = WelcomeEventHandler({ welcomeService })
50
-
51
- // Assert
52
- expect(handler).toBeTypeOf('function')
53
- })
54
-
55
- it('should welcome the name carried by the event', () => {
56
- // Arrange
57
- const welcomeService = WelcomeService({ logger: mockedLogger })
58
- const handler = WelcomeEventHandler({ welcomeService })
59
- const event = { get: () => 'World' } as unknown as IncomingHttpEvent
60
-
61
- // Act
62
- const response = handler(event)
63
-
64
- // Assert
65
- expect(response.message).toBe('Hello World! Welcome to Stone.js.')
66
- expect(response.framework.name).toBe('Stone.js')
67
- expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
1
+ import { createTestApp, makeIncomingHttpEvent } from '@stone-js/testing'
2
+
3
+ /**
4
+ * The whole application, booted in memory and asked a real question.
5
+ *
6
+ * Nothing is mocked and nothing is listed: `createTestApp()` discovers `app/**`, and the event goes
7
+ * through the same kernel production runs. If this passes the application works; if it fails the
8
+ * application is broken. That is the only kind of test worth shipping in a starter — the previous one
9
+ * stubbed out the framework's own decorators, which meant it could pass while nothing worked.
10
+ */
11
+ describe('Application', () => {
12
+ it('answers the caller', async () => {
13
+ const app = await createTestApp()
14
+
15
+ const response = await app.send(makeIncomingHttpEvent({ method: 'GET', url: '/?name=Ada' }))
16
+
17
+ expect(response.statusCode).toBe(200)
18
+ expect(response.json()).toMatchObject({ message: expect.stringContaining('Ada') })
68
19
  })
69
20
 
70
- it('should fall back to the default name when the event carries none', () => {
71
- // Arrange
72
- const welcomeService = WelcomeService({ logger: mockedLogger })
73
- const handler = WelcomeEventHandler({ welcomeService })
74
- const event = { get: (_key: string, fallback: string) => fallback } as unknown as IncomingHttpEvent
21
+ it('answers when nobody says who they are', async () => {
22
+ const app = await createTestApp()
75
23
 
76
- // Act
77
- const response = handler(event)
24
+ const response = await app.send(makeIncomingHttpEvent({ method: 'GET', url: '/' }))
78
25
 
79
- // Assert
80
- expect(response.message).toBe('Hello World! Welcome to Stone.js.')
81
- expect(response.framework.name).toBe('Stone.js')
82
- expect(mockedLogger.info).toHaveBeenCalledWith('Welcome World')
26
+ expect(response.statusCode).toBe(200)
83
27
  })
84
28
  })
@@ -1,24 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
8
- coverage: {
9
- provider: 'v8',
10
- include: ['app/**/*.ts', 'app/**/*.tsx'],
11
- reporter: ['text', 'html'],
12
- reportsDirectory: './coverage',
13
- thresholds: {
14
- 100: true
15
- },
16
- watermarks: {
17
- statements: [60, 80],
18
- functions: [60, 80],
19
- branches: [60, 80],
20
- lines: [60, 80]
21
- }
22
- },
23
- }
24
- });
@@ -1,24 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
8
- coverage: {
9
- provider: 'v8',
10
- include: ['app/**/*.ts', 'app/**/*.tsx'],
11
- reporter: ['text', 'html'],
12
- reportsDirectory: './coverage',
13
- thresholds: {
14
- 100: true
15
- },
16
- watermarks: {
17
- statements: [60, 80],
18
- functions: [60, 80],
19
- branches: [60, 80],
20
- lines: [60, 80]
21
- }
22
- },
23
- }
24
- });
@@ -1,24 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
8
- coverage: {
9
- provider: 'v8',
10
- include: ['app/**/*.ts'],
11
- reporter: ['text', 'html'],
12
- reportsDirectory: './coverage',
13
- thresholds: {
14
- 100: true
15
- },
16
- watermarks: {
17
- statements: [60, 80],
18
- functions: [60, 80],
19
- branches: [60, 80],
20
- lines: [60, 80]
21
- }
22
- },
23
- }
24
- });
@@ -1,24 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
8
- coverage: {
9
- provider: 'v8',
10
- include: ['app/**/*.ts'],
11
- reporter: ['text', 'html'],
12
- reportsDirectory: './coverage',
13
- thresholds: {
14
- 100: true
15
- },
16
- watermarks: {
17
- statements: [60, 80],
18
- functions: [60, 80],
19
- branches: [60, 80],
20
- lines: [60, 80]
21
- }
22
- },
23
- }
24
- });
@@ -1,41 +0,0 @@
1
- import { renderToString } from 'react-dom/server'
2
- import { HomePage } from '../app/pages/HomePage'
3
-
4
- // Mock the page decorator so the class can be instantiated without a running app context.
5
- vi.mock('@stone-js/use-react', async (importOriginal) => {
6
- const actual: any = await importOriginal()
7
- return {
8
- ...actual,
9
- Page: vi.fn(() => vi.fn())
10
- }
11
- })
12
-
13
- describe('HomePage', () => {
14
- it('returns the domain message from handle', () => {
15
- // Arrange
16
- const page = new HomePage()
17
-
18
- // Act
19
- const data = page.handle()
20
-
21
- // Assert
22
- expect(data.message).toBe('Write your domain once. Stone.js applies the context.')
23
- })
24
-
25
- it('renders the Stone.js logo and the message', () => {
26
- // Arrange
27
- const page = new HomePage()
28
-
29
- // Act
30
- const html = renderToString(page.render({ data: page.handle() } as any))
31
-
32
- // Assert: the premium welcome hero renders the Stone.js logo (Vite inlines the small SVG
33
- // as a data URI), the brand title and the domain message.
34
- expect(html).toContain('stone-welcome')
35
- expect(html).toContain('<img')
36
- expect(html).toContain('image/svg+xml')
37
- expect(html).toContain('alt="Stone.js"')
38
- expect(html).toContain('Stone.js')
39
- expect(html).toContain('Write your domain once')
40
- })
41
- })
@@ -1,31 +0,0 @@
1
- import { fileURLToPath } from 'node:url'
2
- import { defineConfig } from 'vitest/config'
3
-
4
- export default defineConfig({
5
- // Mirror the CLI's static-asset aliases (see stone.config.mjs) so component imports like
6
- // `import logo from '@img/logo.svg'` also resolve under the test runner.
7
- resolve: {
8
- alias: {
9
- '@img': fileURLToPath(new URL('./assets/images', import.meta.url)),
10
- '@css': fileURLToPath(new URL('./assets/css', import.meta.url)),
11
- '@assets': fileURLToPath(new URL('./assets', import.meta.url))
12
- }
13
- },
14
- test: {
15
- globals: true,
16
- environment: 'node',
17
- include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
18
- coverage: {
19
- provider: 'v8',
20
- include: ['app/**/*.ts', 'app/**/*.tsx'],
21
- reporter: ['text', 'html'],
22
- reportsDirectory: './coverage',
23
- watermarks: {
24
- statements: [60, 80],
25
- functions: [60, 80],
26
- branches: [60, 80],
27
- lines: [60, 80]
28
- }
29
- }
30
- }
31
- })
@@ -1,51 +0,0 @@
1
- import { renderToString } from 'react-dom/server'
2
- import { AppLayout } from '../app/layout/AppLayout/AppLayout'
3
-
4
- // We must mock decorators and router-bound components to lighten the test environment
5
- vi.mock('@stone-js/use-react', async (importOriginal) => {
6
- const actual: any = await importOriginal()
7
- return {
8
- ...actual,
9
- PageLayout: vi.fn(() => vi.fn()),
10
- StoneLink: ({ children }: any) => children,
11
- StoneOutlet: ({ children }: any) => children
12
- }
13
- })
14
-
15
- describe('AppLayout', () => {
16
- let layout: AppLayout
17
-
18
- beforeEach(() => {
19
- layout = new AppLayout({} as any)
20
- })
21
-
22
- const render = (): string => {
23
- const container = {
24
- make: () => ({ getUser: () => undefined })
25
- }
26
- return renderToString(layout.render({ container, children: null } as any))
27
- }
28
-
29
- it('should create an App Layout instance', () => {
30
- // Assert
31
- expect(layout).toBeInstanceOf(AppLayout)
32
- })
33
-
34
- it('should render the real Stone.js logo', () => {
35
- // Act
36
- const html = render()
37
-
38
- // Assert
39
- expect(html).toContain('/logo.svg')
40
- expect(html).toContain('alt="Stone.js"')
41
- })
42
-
43
- it('should render the unauthenticated header', () => {
44
- // Act
45
- const html = render()
46
-
47
- // Assert
48
- expect(html).toContain('Login')
49
- expect(html).toContain('Stone.js')
50
- })
51
- })
@@ -1,38 +0,0 @@
1
- import { renderToString } from 'react-dom/server'
2
- import { HomePage } from '../app/pages/home/HomePage'
3
-
4
- // We must mock the @Page decorator and router-bound components to lighten the test environment
5
- vi.mock('@stone-js/use-react', async (importOriginal) => {
6
- const actual: any = await importOriginal()
7
- return {
8
- ...actual,
9
- Page: vi.fn(() => vi.fn()),
10
- StoneLink: ({ children }: any) => children
11
- }
12
- })
13
-
14
- describe('HomePage', () => {
15
- const render = (): string => {
16
- const page = new HomePage()
17
- return renderToString(page.render())
18
- }
19
-
20
- it('should render the premium Stone.js welcome hero with the real logo', () => {
21
- // Act
22
- const html = render()
23
-
24
- // Assert
25
- expect(html).toContain('/logo.svg')
26
- expect(html).toContain('alt="Stone.js"')
27
- })
28
-
29
- it('should render the Welcome to Stone.js headline', () => {
30
- // Act
31
- const html = render()
32
-
33
- // Assert
34
- expect(html).toContain('Welcome')
35
- expect(html).toContain('Stone.js')
36
- expect(html).toContain('stone-welcome')
37
- })
38
- })
@@ -1,24 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- include: ['./tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
8
- coverage: {
9
- provider: 'v8',
10
- include: ['app/**/*.ts', 'app/**/*.tsx'],
11
- reporter: ['text', 'html'],
12
- reportsDirectory: './coverage',
13
- thresholds: {
14
- 100: true
15
- },
16
- watermarks: {
17
- statements: [60, 80],
18
- functions: [60, 80],
19
- branches: [60, 80],
20
- lines: [60, 80]
21
- }
22
- },
23
- }
24
- });
@@ -1,45 +0,0 @@
1
- import { renderToString } from 'react-dom/server'
2
- import { HomePage } from '../app/pages/home/HomePage'
3
-
4
- // We must mock router-bound components to lighten the test environment
5
- vi.mock('@stone-js/use-react', async (importOriginal) => {
6
- const actual: any = await importOriginal()
7
- return {
8
- ...actual,
9
- StoneLink: ({ children }: any) => children
10
- }
11
- })
12
-
13
- describe('HomePage', () => {
14
- const render = (data: any[] = []): string => {
15
- const page = HomePage({ postService: {} as any })
16
- return renderToString(page.render?.({ data } as any))
17
- }
18
-
19
- it('should render the premium Stone.js welcome hero with the real logo', () => {
20
- // Act
21
- const html = render()
22
-
23
- // Assert
24
- expect(html).toContain('/logo.svg')
25
- expect(html).toContain('alt="Stone.js"')
26
- })
27
-
28
- it('should render the Welcome to Stone.js headline', () => {
29
- // Act
30
- const html = render()
31
-
32
- // Assert
33
- expect(html).toContain('Welcome')
34
- expect(html).toContain('Stone.js')
35
- expect(html).toContain('stone-welcome')
36
- })
37
-
38
- it('should reflect the number of published posts in the lead', () => {
39
- // Act
40
- const html = render([{ id: 1 }, { id: 2 }])
41
-
42
- // Assert
43
- expect(html).toContain('2 posts')
44
- })
45
- })
@@ -1,39 +0,0 @@
1
- import { createElement } from 'react'
2
- import { renderToString } from 'react-dom/server'
3
- import { LayoutHeader } from '../app/components/LayoutHeader/LayoutHeader'
4
-
5
- // We must mock router-bound components to lighten the test environment
6
- vi.mock('@stone-js/use-react', async (importOriginal) => {
7
- const actual: any = await importOriginal()
8
- return {
9
- ...actual,
10
- StoneLink: ({ children }: any) => children
11
- }
12
- })
13
-
14
- describe('LayoutHeader', () => {
15
- const render = (): string => {
16
- const container = {
17
- make: (key: string) => key === 'event' ? { getUser: () => undefined } : {}
18
- } as any
19
- return renderToString(createElement(LayoutHeader, { container }))
20
- }
21
-
22
- it('should render the real Stone.js logo', () => {
23
- // Act
24
- const html = render()
25
-
26
- // Assert
27
- expect(html).toContain('/logo.svg')
28
- expect(html).toContain('alt="Stone.js"')
29
- })
30
-
31
- it('should render the Stone.js brand for an unauthenticated visitor', () => {
32
- // Act
33
- const html = render()
34
-
35
- // Assert
36
- expect(html).toContain('Stone.js')
37
- expect(html).toContain('app-navbar')
38
- })
39
- })