@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.
- package/README.md +2 -2
- package/basic-react-declarative/app/Application.tsx +0 -2
- package/basic-react-declarative/package.json +7 -7
- package/basic-react-declarative/public/favicon.svg +16 -0
- package/basic-react-declarative/tests/Application.spec.ts +25 -100
- package/basic-react-imperative/app/Application.tsx +2 -17
- package/basic-react-imperative/package.json +7 -7
- package/basic-react-imperative/public/favicon.svg +16 -0
- package/basic-react-imperative/tests/Application.spec.ts +25 -86
- package/basic-react-native-declarative/App.tsx +192 -0
- package/basic-react-native-declarative/LICENSE +21 -0
- package/basic-react-native-declarative/README.md +35 -0
- package/basic-react-native-declarative/adapter/NativeAdapter.ts +108 -0
- package/basic-react-native-declarative/adapter/NativeErrorHandler.ts +53 -0
- package/basic-react-native-declarative/adapter/NativeEventSource.ts +58 -0
- package/basic-react-native-declarative/adapter/RawResponseWrapper.ts +30 -0
- package/basic-react-native-declarative/adapter/declarations.ts +40 -0
- package/basic-react-native-declarative/adapter/middleware.ts +73 -0
- package/basic-react-native-declarative/adapter/nativeAdapterBlueprint.ts +51 -0
- package/basic-react-native-declarative/adapter/renderSink.ts +52 -0
- package/basic-react-native-declarative/app/Application.ts +17 -0
- package/basic-react-native-declarative/app/WelcomeController.ts +66 -0
- package/basic-react-native-declarative/app.json +25 -0
- package/basic-react-native-declarative/assets/android-icon-background.png +0 -0
- package/basic-react-native-declarative/assets/android-icon-foreground.png +0 -0
- package/basic-react-native-declarative/assets/android-icon-monochrome.png +0 -0
- package/basic-react-native-declarative/assets/favicon.png +0 -0
- package/basic-react-native-declarative/assets/icon.png +0 -0
- package/basic-react-native-declarative/assets/splash-icon.png +0 -0
- package/basic-react-native-declarative/babel.config.js +16 -0
- package/basic-react-native-declarative/index.ts +22 -0
- package/basic-react-native-declarative/metro.config.js +7 -0
- package/basic-react-native-declarative/package.json +41 -0
- package/basic-react-native-declarative/tests/Application.spec.ts +65 -0
- package/basic-react-native-declarative/tsconfig.json +16 -0
- package/basic-react-native-declarative/vitest.config.ts +27 -0
- package/basic-service-declarative/app/Application.ts +0 -2
- package/basic-service-declarative/package.json +6 -6
- package/basic-service-declarative/tests/Application.spec.ts +20 -53
- package/basic-service-imperative/app/Application.ts +2 -14
- package/basic-service-imperative/package.json +6 -6
- package/basic-service-imperative/tests/Application.spec.ts +19 -44
- package/continuum-showcase/package.json +11 -10
- package/continuum-showcase/public/favicon.svg +16 -0
- package/continuum-showcase/stone.config.mjs +2 -2
- package/continuum-showcase/tests/application.spec.ts +30 -0
- package/full-react-declarative/app/Application.ts +0 -4
- package/full-react-declarative/package.json +12 -12
- package/full-react-declarative/public/favicon.svg +16 -0
- package/full-react-declarative/stone.config.mjs +2 -2
- package/full-react-declarative/tests/application.spec.ts +30 -0
- package/full-react-imperative/app/Application.ts +1 -3
- package/full-react-imperative/package.json +12 -12
- package/full-react-imperative/public/favicon.svg +16 -0
- package/full-react-imperative/stone.config.mjs +2 -2
- package/full-react-imperative/tests/application.spec.ts +30 -0
- package/full-service-declarative/app/Application.ts +5 -2
- package/full-service-declarative/app/configurations/AppConfiguration.ts +1 -3
- package/full-service-declarative/package.json +13 -12
- package/full-service-declarative/stone.config.mjs +2 -2
- package/full-service-declarative/tests/application.spec.ts +30 -0
- package/full-service-imperative/app/Application.ts +8 -2
- package/full-service-imperative/app/configurations/AppConfiguration.ts +1 -3
- package/full-service-imperative/package.json +13 -12
- package/full-service-imperative/stone.config.mjs +2 -2
- package/full-service-imperative/tests/application.spec.ts +30 -0
- package/package.json +15 -1
- package/standard-react-declarative/package.json +11 -10
- package/standard-react-declarative/public/favicon.svg +16 -0
- package/standard-react-declarative/tests/application.spec.ts +30 -0
- package/standard-react-imperative/package.json +11 -10
- package/standard-react-imperative/public/favicon.svg +16 -0
- package/standard-react-imperative/tests/application.spec.ts +30 -0
- package/standard-service-declarative/package.json +9 -8
- package/standard-service-declarative/tests/Application.spec.ts +22 -94
- package/standard-service-imperative/package.json +9 -8
- package/standard-service-imperative/tests/Application.spec.ts +22 -78
- package/basic-react-declarative/vitest.config.ts +0 -24
- package/basic-react-imperative/vitest.config.ts +0 -24
- package/basic-service-declarative/vitest.config.ts +0 -24
- package/basic-service-imperative/vitest.config.ts +0 -24
- package/continuum-showcase/tests/HomePage.spec.tsx +0 -41
- package/continuum-showcase/vitest.config.ts +0 -31
- package/full-react-declarative/tests/AppLayout.spec.ts +0 -51
- package/full-react-declarative/tests/HomePage.spec.ts +0 -38
- package/full-react-declarative/vitest.config.ts +0 -24
- package/full-react-imperative/tests/HomePage.spec.ts +0 -45
- package/full-react-imperative/tests/LayoutHeader.spec.ts +0 -39
- package/full-react-imperative/vitest.config.ts +0 -24
- package/full-service-declarative/tests/PostService.spec.ts +0 -56
- package/full-service-declarative/tests/WelcomeEventHandler.spec.ts +0 -54
- package/full-service-declarative/vitest.config.ts +0 -24
- package/full-service-imperative/tests/PostService.spec.ts +0 -47
- package/full-service-imperative/tests/WelcomeEventHandler.spec.ts +0 -31
- package/full-service-imperative/vitest.config.ts +0 -24
- package/standard-react-declarative/tests/WelcomePage.spec.ts +0 -71
- package/standard-react-declarative/vitest.config.ts +0 -24
- package/standard-react-imperative/tests/WelcomePage.spec.ts +0 -53
- package/standard-react-imperative/vitest.config.ts +0 -24
- package/standard-service-declarative/vitest.config.ts +0 -24
- 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": "
|
|
18
|
-
"test:cvg": "
|
|
17
|
+
"test": "stone test",
|
|
18
|
+
"test:cvg": "stone test --coverage"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@stone-js/pipeline": "^0.8.
|
|
22
|
-
"@stone-js/http-core": "^0.8.
|
|
23
|
-
"@stone-js/node-http-adapter": "^0.8.
|
|
24
|
-
"@stone-js/router": "^0.8.
|
|
25
|
-
"@stone-js/core": "^0.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.
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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('
|
|
89
|
-
|
|
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
|
-
|
|
93
|
-
const response = handler.welcome(event)
|
|
24
|
+
const response = await app.send(makeIncomingHttpEvent({ method: 'GET', url: '/' }))
|
|
94
25
|
|
|
95
|
-
|
|
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": "
|
|
17
|
-
"test:cvg": "
|
|
16
|
+
"test": "stone test",
|
|
17
|
+
"test:cvg": "stone test --coverage"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@stone-js/pipeline": "^0.8.
|
|
21
|
-
"@stone-js/http-core": "^0.8.
|
|
22
|
-
"@stone-js/node-http-adapter": "^0.8.
|
|
23
|
-
"@stone-js/router": "^0.8.
|
|
24
|
-
"@stone-js/core": "^0.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.
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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('
|
|
71
|
-
|
|
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
|
-
|
|
77
|
-
const response = handler(event)
|
|
24
|
+
const response = await app.send(makeIncomingHttpEvent({ method: 'GET', url: '/' }))
|
|
78
25
|
|
|
79
|
-
|
|
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
|
-
})
|