@qwickapps/react-framework 1.3.4 → 1.4.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/README.md +1688 -2
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +7 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/Html.d.ts +28 -18
- package/dist/components/Html.d.ts.map +1 -1
- package/dist/components/Logo.d.ts +12 -35
- package/dist/components/Logo.d.ts.map +1 -1
- package/dist/components/Markdown.d.ts +18 -13
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/QwickApp.d.ts +16 -3
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/QwickIcon.d.ts +23 -0
- package/dist/components/QwickIcon.d.ts.map +1 -0
- package/dist/components/SafeSpan.d.ts +12 -5
- package/dist/components/SafeSpan.d.ts.map +1 -1
- package/dist/components/Scaffold.d.ts.map +1 -1
- package/dist/components/base/ModelView.d.ts +101 -0
- package/dist/components/base/ModelView.d.ts.map +1 -0
- package/dist/components/base/index.d.ts +11 -0
- package/dist/components/base/index.d.ts.map +1 -0
- package/dist/components/blocks/Article.d.ts +12 -2
- package/dist/components/blocks/Article.d.ts.map +1 -1
- package/dist/components/blocks/Code.d.ts +13 -2
- package/dist/components/blocks/Code.d.ts.map +1 -1
- package/dist/components/blocks/Content.d.ts.map +1 -1
- package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
- package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
- package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
- package/dist/components/blocks/Footer.d.ts.map +1 -1
- package/dist/components/blocks/HeroBlock.d.ts +27 -13
- package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
- package/dist/components/blocks/Image.d.ts +41 -0
- package/dist/components/blocks/Image.d.ts.map +1 -0
- package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
- package/dist/components/blocks/ProductCard.d.ts.map +1 -1
- package/dist/components/blocks/Section.d.ts +16 -2
- package/dist/components/blocks/Section.d.ts.map +1 -1
- package/dist/components/blocks/Text.d.ts +41 -0
- package/dist/components/blocks/Text.d.ts.map +1 -0
- package/dist/components/blocks/index.d.ts +4 -0
- package/dist/components/blocks/index.d.ts.map +1 -1
- package/dist/components/buttons/Button.d.ts +23 -7
- package/dist/components/buttons/Button.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +19 -13
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/ChoiceInputField.d.ts +17 -11
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
- package/dist/components/input/HtmlInputField.d.ts +17 -11
- package/dist/components/input/HtmlInputField.d.ts.map +1 -1
- package/dist/components/input/SelectInputField.d.ts +16 -10
- package/dist/components/input/SelectInputField.d.ts.map +1 -1
- package/dist/components/input/SwitchInputField.d.ts +16 -10
- package/dist/components/input/SwitchInputField.d.ts.map +1 -1
- package/dist/components/input/TextField.d.ts.map +1 -1
- package/dist/components/input/TextInputField.d.ts +16 -11
- package/dist/components/input/TextInputField.d.ts.map +1 -1
- package/dist/components/layout/GridCell.d.ts +23 -6
- package/dist/components/layout/GridCell.d.ts.map +1 -1
- package/dist/components/layout/GridLayout.d.ts +24 -23
- package/dist/components/layout/GridLayout.d.ts.map +1 -1
- package/dist/components/pages/FormPage.d.ts.map +1 -1
- package/dist/components/pages/Page.d.ts +49 -87
- package/dist/components/pages/Page.d.ts.map +1 -1
- package/dist/components/pages/index.d.ts +2 -2
- package/dist/components/pages/index.d.ts.map +1 -1
- package/dist/config/AppConfig.d.ts +49 -0
- package/dist/config/AppConfig.d.ts.map +1 -0
- package/dist/config/AppConfigBuilder.d.ts +75 -0
- package/dist/config/AppConfigBuilder.d.ts.map +1 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/types.d.ts +130 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.esm.js +451 -0
- package/dist/config.js +455 -0
- package/dist/contexts/PrintModeContext.d.ts +27 -0
- package/dist/contexts/PrintModeContext.d.ts.map +1 -0
- package/dist/contexts/QwickAppContext.d.ts +2 -2
- package/dist/contexts/QwickAppContext.d.ts.map +1 -1
- package/dist/contexts/ThemeContext.d.ts.map +1 -1
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/usePrintMode.d.ts +39 -0
- package/dist/hooks/usePrintMode.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +20722 -16021
- package/dist/index.js +20725 -16010
- package/dist/schemas/CodeSchema.d.ts +2 -1
- package/dist/schemas/CodeSchema.d.ts.map +1 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
- package/dist/schemas/ContentSchema.d.ts +2 -1
- package/dist/schemas/ContentSchema.d.ts.map +1 -1
- package/dist/schemas/GridCellSchema.d.ts +25 -0
- package/dist/schemas/GridCellSchema.d.ts.map +1 -0
- package/dist/schemas/GridLayoutSchema.d.ts +23 -0
- package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
- package/dist/schemas/HtmlSchema.d.ts +14 -0
- package/dist/schemas/HtmlSchema.d.ts.map +1 -0
- package/dist/schemas/ImageSchema.d.ts +32 -0
- package/dist/schemas/ImageSchema.d.ts.map +1 -0
- package/dist/schemas/LogoSchema.d.ts +35 -0
- package/dist/schemas/LogoSchema.d.ts.map +1 -0
- package/dist/schemas/MarkdownSchema.d.ts +14 -0
- package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/schemas/PageTemplateSchema.d.ts +31 -0
- package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
- package/dist/schemas/PrintConfigSchema.d.ts +31 -0
- package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
- package/dist/schemas/SectionSchema.d.ts +2 -1
- package/dist/schemas/SectionSchema.d.ts.map +1 -1
- package/dist/schemas/TextSchema.d.ts +37 -0
- package/dist/schemas/TextSchema.d.ts.map +1 -0
- package/dist/schemas/ViewModelSchema.d.ts +23 -0
- package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +15 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
- package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
- package/dist/schemas/transformers/registry.d.ts +15 -0
- package/dist/schemas/transformers/registry.d.ts.map +1 -0
- package/dist/schemas/types/Serializable.d.ts +46 -0
- package/dist/schemas/types/Serializable.d.ts.map +1 -0
- package/dist/utils/htmlTransform.d.ts.map +1 -1
- package/dist/utils/reactUtils.d.ts +12 -3
- package/dist/utils/reactUtils.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
- package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
- package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
- package/src/__tests__/components/Logo.test.js +3 -3
- package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
- package/src/__tests__/components/base/ModelView.test.tsx +220 -0
- package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
- package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
- package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
- package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
- package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
- package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
- package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
- package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
- package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
- package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
- package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
- package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
- package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
- package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
- package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
- package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
- package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
- package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
- package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
- package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
- package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
- package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
- package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
- package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
- package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
- package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
- package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
- package/src/components/ErrorBoundary.tsx +8 -8
- package/src/components/Html.tsx +147 -44
- package/src/components/Logo.tsx +198 -100
- package/src/components/Markdown.tsx +125 -16
- package/src/components/QwickApp.tsx +64 -31
- package/src/components/QwickIcon.tsx +59 -0
- package/src/components/SafeSpan.tsx +65 -10
- package/src/components/Scaffold.tsx +2 -8
- package/src/components/base/ModelView.tsx +199 -0
- package/src/components/base/index.ts +11 -0
- package/src/components/blocks/Article.tsx +57 -18
- package/src/components/blocks/Code.md +529 -0
- package/src/components/blocks/Code.tsx +102 -15
- package/src/components/blocks/Content.tsx +25 -77
- package/src/components/blocks/CoverImageHeader.tsx +9 -4
- package/src/components/blocks/FeatureCard.tsx +1 -2
- package/src/components/blocks/FeatureGrid.tsx +19 -1
- package/src/components/blocks/Footer.tsx +13 -1
- package/src/components/blocks/HeroBlock.tsx +87 -20
- package/src/components/blocks/Image.tsx +395 -0
- package/src/components/blocks/PageBannerHeader.tsx +14 -12
- package/src/components/blocks/ProductCard.tsx +51 -52
- package/src/components/blocks/Section.tsx +113 -8
- package/src/components/blocks/Text.tsx +285 -0
- package/src/components/blocks/index.ts +4 -0
- package/src/components/buttons/Button.tsx +184 -15
- package/src/components/forms/FormBlock.tsx +70 -17
- package/src/components/index.ts +5 -0
- package/src/components/input/ChoiceInputField.tsx +48 -18
- package/src/components/input/HtmlInputField.tsx +48 -18
- package/src/components/input/SelectInputField.tsx +48 -16
- package/src/components/input/SwitchInputField.tsx +48 -17
- package/src/components/input/TextField.tsx +41 -1
- package/src/components/input/TextInputField.tsx +52 -18
- package/src/components/layout/GridCell.tsx +118 -9
- package/src/components/layout/GridLayout.tsx +125 -24
- package/src/components/pages/FormPage.tsx +0 -1
- package/src/components/pages/Page.css +304 -332
- package/src/components/pages/Page.tsx +307 -255
- package/src/components/pages/index.ts +2 -2
- package/src/config/AppConfig.ts +133 -0
- package/src/config/AppConfigBuilder.ts +421 -0
- package/src/config/__tests__/AppConfig.test.ts +385 -0
- package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
- package/src/config/index.ts +24 -0
- package/src/config/types.ts +170 -0
- package/src/config.ts +25 -0
- package/src/contexts/PrintModeContext.tsx +332 -0
- package/src/contexts/QwickAppContext.tsx +2 -2
- package/src/contexts/ThemeContext.tsx +1 -2
- package/src/contexts/index.ts +2 -0
- package/src/hooks/index.ts +5 -1
- package/src/hooks/usePrintMode.ts +73 -0
- package/src/index.ts +3 -0
- package/src/schemas/CodeSchema.ts +3 -3
- package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
- package/src/schemas/ContentSchema.ts +2 -1
- package/src/schemas/GridCellSchema.ts +164 -0
- package/src/schemas/GridLayoutSchema.ts +133 -0
- package/src/schemas/HtmlSchema.ts +47 -0
- package/src/schemas/ImageSchema.ts +235 -0
- package/src/schemas/LogoSchema.ts +241 -0
- package/src/schemas/MarkdownSchema.ts +47 -0
- package/src/schemas/PageTemplateSchema.ts +186 -0
- package/src/schemas/PrintConfigSchema.ts +207 -0
- package/src/schemas/README.md +661 -0
- package/src/schemas/SectionSchema.ts +2 -1
- package/src/schemas/TextSchema.ts +329 -0
- package/src/schemas/ViewModelSchema.ts +115 -0
- package/src/schemas/index.ts +21 -2
- package/src/schemas/transformers/ComponentTransformer.ts +403 -0
- package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
- package/src/schemas/transformers/registry.ts +72 -0
- package/src/schemas/types/Serializable.ts +51 -0
- package/src/stories/AccessibilityProvider.stories.tsx +253 -253
- package/src/stories/Article.stories.tsx +433 -433
- package/src/stories/Button.stories.tsx +1 -1
- package/src/stories/CardListGrid.stories.tsx +451 -451
- package/src/stories/ChoiceInputField.stories.tsx +503 -503
- package/src/stories/Code.stories.tsx +1 -1
- package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
- package/src/stories/Content.stories.tsx +393 -393
- package/src/stories/CoverImageHeader.stories.tsx +701 -701
- package/src/stories/DataBinding.advanced.stories.tsx +432 -432
- package/src/stories/DataProvider.stories.tsx +1192 -1192
- package/src/stories/FeatureCard.stories.tsx +557 -557
- package/src/stories/FeatureGrid.stories.tsx +594 -594
- package/src/stories/Footer.stories.tsx +640 -640
- package/src/stories/FormBlock.stories.tsx +760 -760
- package/src/stories/FormComponents.stories.tsx +349 -541
- package/src/stories/GridCell.stories.tsx +417 -0
- package/src/stories/GridLayout.stories.tsx +353 -0
- package/src/stories/HeroBlock.stories.tsx +862 -373
- package/src/stories/HtmlInputField.stories.tsx +474 -474
- package/src/stories/Image.stories.tsx +819 -0
- package/src/stories/Introduction.stories.tsx +667 -667
- package/src/stories/LayoutBlocks.stories.tsx +324 -324
- package/src/stories/Logo.stories.tsx +165 -6
- package/src/stories/Markdown.stories.tsx +137 -137
- package/src/stories/ModelView.stories.tsx +477 -0
- package/src/stories/Page.stories.tsx +688 -688
- package/src/stories/PageBannerHeader.stories.tsx +864 -864
- package/src/stories/PaletteSwitcher.stories.tsx +119 -119
- package/src/stories/ProductCard.stories.tsx +424 -424
- package/src/stories/QwickApp.stories.tsx +368 -368
- package/src/stories/ResponsiveMenu.stories.tsx +249 -249
- package/src/stories/SafeSpan.stories.tsx +531 -531
- package/src/stories/Section.stories.tsx +90 -2
- package/src/stories/SelectInputField.stories.tsx +524 -524
- package/src/stories/Text.stories.tsx +560 -0
- package/src/stories/TextInputField.stories.tsx +443 -443
- package/src/stories/ThemeSwitcher.stories.tsx +123 -123
- package/src/utils/htmlTransform.tsx +74 -53
- package/src/utils/reactUtils.tsx +57 -6
- package/dist/index.bundled.css +0 -12
- /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
- /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Component Performance Tests
|
|
3
|
+
*
|
|
4
|
+
* Performance benchmarks and optimization tests for the Text component
|
|
5
|
+
* to ensure it meets the established performance targets (<1ms serialization).
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { render } from '@testing-library/react';
|
|
12
|
+
import '@testing-library/jest-dom';
|
|
13
|
+
import { ComponentTransformer } from '../../../schemas/transformers/ComponentTransformer';
|
|
14
|
+
import { Text } from '../../../components/blocks/Text';
|
|
15
|
+
|
|
16
|
+
describe('Text Performance', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
// Clear component registry for clean tests
|
|
19
|
+
ComponentTransformer.clearRegistry();
|
|
20
|
+
|
|
21
|
+
// Register Text component
|
|
22
|
+
ComponentTransformer.registerComponent(Text as any);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
ComponentTransformer.clearRegistry();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('Serialization Performance', () => {
|
|
30
|
+
it('should serialize simple text in under 1ms', () => {
|
|
31
|
+
const component = <Text content="Simple performance test" variant="body1" />;
|
|
32
|
+
|
|
33
|
+
const iterations = 100;
|
|
34
|
+
const times: number[] = [];
|
|
35
|
+
|
|
36
|
+
// Warm up
|
|
37
|
+
for (let i = 0; i < 10; i++) {
|
|
38
|
+
ComponentTransformer.serialize(component);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Measure
|
|
42
|
+
for (let i = 0; i < iterations; i++) {
|
|
43
|
+
const startTime = performance.now();
|
|
44
|
+
ComponentTransformer.serialize(component);
|
|
45
|
+
const endTime = performance.now();
|
|
46
|
+
times.push(endTime - startTime);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
50
|
+
const maxTime = Math.max(...times);
|
|
51
|
+
|
|
52
|
+
expect(averageTime).toBeLessThan(1); // Average under 1ms
|
|
53
|
+
expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should serialize complex text with all properties in under 1ms', () => {
|
|
57
|
+
const component = (
|
|
58
|
+
<Text
|
|
59
|
+
content="Complex performance test with many properties"
|
|
60
|
+
variant="h2"
|
|
61
|
+
color="primary"
|
|
62
|
+
align="center"
|
|
63
|
+
component="h1"
|
|
64
|
+
fontWeight="bold"
|
|
65
|
+
textDecoration="underline"
|
|
66
|
+
textTransform="uppercase"
|
|
67
|
+
noWrap={true}
|
|
68
|
+
paragraph={false}
|
|
69
|
+
gutterBottom={true}
|
|
70
|
+
fontSize="2.5rem"
|
|
71
|
+
lineHeight="1.2"
|
|
72
|
+
letterSpacing="0.1em"
|
|
73
|
+
fontFamily="Arial, sans-serif"
|
|
74
|
+
customColor="#1976d2"
|
|
75
|
+
maxWidth="600px"
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const iterations = 100;
|
|
80
|
+
const times: number[] = [];
|
|
81
|
+
|
|
82
|
+
// Warm up
|
|
83
|
+
for (let i = 0; i < 10; i++) {
|
|
84
|
+
ComponentTransformer.serialize(component);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Measure
|
|
88
|
+
for (let i = 0; i < iterations; i++) {
|
|
89
|
+
const startTime = performance.now();
|
|
90
|
+
ComponentTransformer.serialize(component);
|
|
91
|
+
const endTime = performance.now();
|
|
92
|
+
times.push(endTime - startTime);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
96
|
+
const maxTime = Math.max(...times);
|
|
97
|
+
|
|
98
|
+
expect(averageTime).toBeLessThan(1); // Average under 1ms
|
|
99
|
+
expect(maxTime).toBeLessThan(20); // Even worst case under 20ms (test environment can have spikes)
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should serialize large text content efficiently', () => {
|
|
103
|
+
const largeContent = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '.repeat(200); // ~11KB
|
|
104
|
+
const component = (
|
|
105
|
+
<Text
|
|
106
|
+
content={largeContent}
|
|
107
|
+
variant="body1"
|
|
108
|
+
paragraph={true}
|
|
109
|
+
maxWidth="800px"
|
|
110
|
+
/>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const iterations = 50;
|
|
114
|
+
const times: number[] = [];
|
|
115
|
+
|
|
116
|
+
// Warm up
|
|
117
|
+
for (let i = 0; i < 5; i++) {
|
|
118
|
+
ComponentTransformer.serialize(component);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Measure
|
|
122
|
+
for (let i = 0; i < iterations; i++) {
|
|
123
|
+
const startTime = performance.now();
|
|
124
|
+
ComponentTransformer.serialize(component);
|
|
125
|
+
const endTime = performance.now();
|
|
126
|
+
times.push(endTime - startTime);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
130
|
+
const maxTime = Math.max(...times);
|
|
131
|
+
|
|
132
|
+
expect(averageTime).toBeLessThan(2); // Large content under 2ms average
|
|
133
|
+
expect(maxTime).toBeLessThan(5); // Even worst case under 5ms
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('Deserialization Performance', () => {
|
|
138
|
+
it('should deserialize simple text in under 1ms', () => {
|
|
139
|
+
const component = <Text content="Simple deserialization test" variant="body1" />;
|
|
140
|
+
const serialized = ComponentTransformer.serialize(component);
|
|
141
|
+
|
|
142
|
+
const iterations = 100;
|
|
143
|
+
const times: number[] = [];
|
|
144
|
+
|
|
145
|
+
// Warm up
|
|
146
|
+
for (let i = 0; i < 10; i++) {
|
|
147
|
+
ComponentTransformer.deserialize(serialized);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Measure
|
|
151
|
+
for (let i = 0; i < iterations; i++) {
|
|
152
|
+
const startTime = performance.now();
|
|
153
|
+
ComponentTransformer.deserialize(serialized);
|
|
154
|
+
const endTime = performance.now();
|
|
155
|
+
times.push(endTime - startTime);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
159
|
+
const maxTime = Math.max(...times);
|
|
160
|
+
|
|
161
|
+
expect(averageTime).toBeLessThan(1); // Average under 1ms
|
|
162
|
+
expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should deserialize complex text in under 1ms', () => {
|
|
166
|
+
const component = (
|
|
167
|
+
<Text
|
|
168
|
+
content="Complex deserialization test"
|
|
169
|
+
variant="h3"
|
|
170
|
+
color="secondary"
|
|
171
|
+
align="right"
|
|
172
|
+
fontWeight="600"
|
|
173
|
+
textDecoration="overline"
|
|
174
|
+
textTransform="capitalize"
|
|
175
|
+
gutterBottom={true}
|
|
176
|
+
fontSize="1.8rem"
|
|
177
|
+
customColor="#ff5722"
|
|
178
|
+
/>
|
|
179
|
+
);
|
|
180
|
+
const serialized = ComponentTransformer.serialize(component);
|
|
181
|
+
|
|
182
|
+
const iterations = 100;
|
|
183
|
+
const times: number[] = [];
|
|
184
|
+
|
|
185
|
+
// Warm up
|
|
186
|
+
for (let i = 0; i < 10; i++) {
|
|
187
|
+
ComponentTransformer.deserialize(serialized);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Measure
|
|
191
|
+
for (let i = 0; i < iterations; i++) {
|
|
192
|
+
const startTime = performance.now();
|
|
193
|
+
ComponentTransformer.deserialize(serialized);
|
|
194
|
+
const endTime = performance.now();
|
|
195
|
+
times.push(endTime - startTime);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
199
|
+
const maxTime = Math.max(...times);
|
|
200
|
+
|
|
201
|
+
expect(averageTime).toBeLessThan(1); // Average under 1ms
|
|
202
|
+
expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe('Round-trip Performance', () => {
|
|
207
|
+
it.skip('should complete serialize → deserialize → render cycle efficiently', () => {
|
|
208
|
+
const component = (
|
|
209
|
+
<Text
|
|
210
|
+
content="Round-trip performance test"
|
|
211
|
+
variant="h4"
|
|
212
|
+
color="info"
|
|
213
|
+
fontWeight="bold"
|
|
214
|
+
gutterBottom={true}
|
|
215
|
+
/>
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const iterations = 50;
|
|
219
|
+
const times: number[] = [];
|
|
220
|
+
|
|
221
|
+
// Warm up
|
|
222
|
+
for (let i = 0; i < 5; i++) {
|
|
223
|
+
const serialized = ComponentTransformer.serialize(component);
|
|
224
|
+
const deserialized = ComponentTransformer.deserialize(serialized);
|
|
225
|
+
render(deserialized as React.ReactElement);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Measure complete round-trip
|
|
229
|
+
for (let i = 0; i < iterations; i++) {
|
|
230
|
+
const startTime = performance.now();
|
|
231
|
+
|
|
232
|
+
const serialized = ComponentTransformer.serialize(component);
|
|
233
|
+
const deserialized = ComponentTransformer.deserialize(serialized);
|
|
234
|
+
const { container } = render(deserialized as React.ReactElement);
|
|
235
|
+
|
|
236
|
+
// Ensure DOM is actually updated
|
|
237
|
+
container.querySelector('.MuiTypography-root');
|
|
238
|
+
|
|
239
|
+
const endTime = performance.now();
|
|
240
|
+
times.push(endTime - startTime);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
244
|
+
const maxTime = Math.max(...times);
|
|
245
|
+
|
|
246
|
+
expect(averageTime).toBeLessThan(5); // Complete round-trip under 5ms average
|
|
247
|
+
expect(maxTime).toBeLessThan(20); // Even worst case under 20ms (DOM rendering can be slow in tests)
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('Memory Performance', () => {
|
|
252
|
+
it('should not create memory leaks during serialization', () => {
|
|
253
|
+
const component = <Text content="Memory leak test" variant="body1" />;
|
|
254
|
+
|
|
255
|
+
// Get initial memory usage (if available)
|
|
256
|
+
const initialMemory = (performance as any).memory?.usedJSHeapSize || 0;
|
|
257
|
+
|
|
258
|
+
// Perform many serialization operations
|
|
259
|
+
for (let i = 0; i < 1000; i++) {
|
|
260
|
+
ComponentTransformer.serialize(component);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Force garbage collection if available
|
|
264
|
+
if ((global as any).gc) {
|
|
265
|
+
(global as any).gc();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Check memory hasn't grown significantly
|
|
269
|
+
const finalMemory = (performance as any).memory?.usedJSHeapSize || 0;
|
|
270
|
+
|
|
271
|
+
if (initialMemory > 0) {
|
|
272
|
+
const memoryGrowth = finalMemory - initialMemory;
|
|
273
|
+
const memoryGrowthMB = memoryGrowth / (1024 * 1024);
|
|
274
|
+
|
|
275
|
+
// Should not grow by more than 1MB for 1000 serializations
|
|
276
|
+
expect(memoryGrowthMB).toBeLessThan(1);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should handle large batch operations efficiently', () => {
|
|
281
|
+
const components = Array.from({ length: 100 }, (_, i) => (
|
|
282
|
+
<Text
|
|
283
|
+
content={`Batch test item ${i}`}
|
|
284
|
+
variant={i % 2 === 0 ? 'h3' : 'body1'}
|
|
285
|
+
color={i % 3 === 0 ? 'primary' : 'textSecondary'}
|
|
286
|
+
/>
|
|
287
|
+
));
|
|
288
|
+
|
|
289
|
+
const startTime = performance.now();
|
|
290
|
+
|
|
291
|
+
// Serialize all components
|
|
292
|
+
const serialized = components.map(component => ComponentTransformer.serialize(component));
|
|
293
|
+
|
|
294
|
+
// Deserialize all components
|
|
295
|
+
const deserialized = serialized.map(data => ComponentTransformer.deserialize(data));
|
|
296
|
+
|
|
297
|
+
const endTime = performance.now();
|
|
298
|
+
const totalTime = endTime - startTime;
|
|
299
|
+
|
|
300
|
+
expect(serialized).toHaveLength(100);
|
|
301
|
+
expect(deserialized).toHaveLength(100);
|
|
302
|
+
expect(totalTime).toBeLessThan(100); // 100 components in under 100ms (1ms per component)
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
describe('Rendering Performance', () => {
|
|
307
|
+
it.skip('should render efficiently with default props', () => {
|
|
308
|
+
const component = <Text content="Render performance test" />;
|
|
309
|
+
|
|
310
|
+
const iterations = 100;
|
|
311
|
+
const times: number[] = [];
|
|
312
|
+
|
|
313
|
+
// Warm up React rendering
|
|
314
|
+
for (let i = 0; i < 10; i++) {
|
|
315
|
+
render(component);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Measure rendering time
|
|
319
|
+
for (let i = 0; i < iterations; i++) {
|
|
320
|
+
const startTime = performance.now();
|
|
321
|
+
render(component);
|
|
322
|
+
const endTime = performance.now();
|
|
323
|
+
times.push(endTime - startTime);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const averageTime = times.reduce((sum, time) => sum + time, 0) / times.length;
|
|
327
|
+
const maxTime = Math.max(...times);
|
|
328
|
+
|
|
329
|
+
expect(averageTime).toBeLessThan(3); // Average render under 3ms
|
|
330
|
+
expect(maxTime).toBeLessThan(10); // Even worst case under 10ms
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it('should render large text content efficiently', () => {
|
|
334
|
+
const largeContent = 'Lorem ipsum dolor sit amet. '.repeat(500); // ~14KB
|
|
335
|
+
const component = <Text content={largeContent} variant="body1" />;
|
|
336
|
+
|
|
337
|
+
const startTime = performance.now();
|
|
338
|
+
render(component);
|
|
339
|
+
const endTime = performance.now();
|
|
340
|
+
|
|
341
|
+
expect(endTime - startTime).toBeLessThan(10); // Large content render under 10ms
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it('should handle rapid prop changes efficiently', () => {
|
|
345
|
+
const { rerender } = render(<Text content="Initial" variant="body1" />);
|
|
346
|
+
|
|
347
|
+
const startTime = performance.now();
|
|
348
|
+
|
|
349
|
+
// Simulate rapid prop changes
|
|
350
|
+
for (let i = 0; i < 50; i++) {
|
|
351
|
+
rerender(
|
|
352
|
+
<Text
|
|
353
|
+
content={`Update ${i}`}
|
|
354
|
+
variant={i % 2 === 0 ? 'h4' : 'body2'}
|
|
355
|
+
color={i % 3 === 0 ? 'primary' : 'textSecondary'}
|
|
356
|
+
/>
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const endTime = performance.now();
|
|
361
|
+
const totalTime = endTime - startTime;
|
|
362
|
+
|
|
363
|
+
expect(totalTime).toBeLessThan(100); // 50 re-renders under 100ms (2ms per update)
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
describe('Performance Targets Validation', () => {
|
|
368
|
+
it('should meet all performance targets consistently', () => {
|
|
369
|
+
const simpleComponent = <Text content="Performance target test" />;
|
|
370
|
+
const complexComponent = (
|
|
371
|
+
<Text
|
|
372
|
+
content="Complex performance target test"
|
|
373
|
+
variant="h2"
|
|
374
|
+
color="primary"
|
|
375
|
+
align="center"
|
|
376
|
+
fontWeight="bold"
|
|
377
|
+
fontSize="2rem"
|
|
378
|
+
customColor="#1976d2"
|
|
379
|
+
gutterBottom={true}
|
|
380
|
+
/>
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
// Test multiple iterations for consistency
|
|
384
|
+
const results = {
|
|
385
|
+
simpleSerialize: [] as number[],
|
|
386
|
+
simpleDeserialize: [] as number[],
|
|
387
|
+
complexSerialize: [] as number[],
|
|
388
|
+
complexDeserialize: [] as number[]
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// Warm up
|
|
392
|
+
for (let i = 0; i < 10; i++) {
|
|
393
|
+
ComponentTransformer.serialize(simpleComponent);
|
|
394
|
+
ComponentTransformer.serialize(complexComponent);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Measure
|
|
398
|
+
for (let i = 0; i < 100; i++) {
|
|
399
|
+
// Simple serialize
|
|
400
|
+
let start = performance.now();
|
|
401
|
+
ComponentTransformer.serialize(simpleComponent);
|
|
402
|
+
results.simpleSerialize.push(performance.now() - start);
|
|
403
|
+
|
|
404
|
+
// Simple deserialize
|
|
405
|
+
const simpleSerialized = ComponentTransformer.serialize(simpleComponent);
|
|
406
|
+
start = performance.now();
|
|
407
|
+
ComponentTransformer.deserialize(simpleSerialized);
|
|
408
|
+
results.simpleDeserialize.push(performance.now() - start);
|
|
409
|
+
|
|
410
|
+
// Complex serialize
|
|
411
|
+
start = performance.now();
|
|
412
|
+
ComponentTransformer.serialize(complexComponent);
|
|
413
|
+
results.complexSerialize.push(performance.now() - start);
|
|
414
|
+
|
|
415
|
+
// Complex deserialize
|
|
416
|
+
const complexSerialized = ComponentTransformer.serialize(complexComponent);
|
|
417
|
+
start = performance.now();
|
|
418
|
+
ComponentTransformer.deserialize(complexSerialized);
|
|
419
|
+
results.complexDeserialize.push(performance.now() - start);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Calculate statistics
|
|
423
|
+
const stats = Object.entries(results).map(([key, times]) => ({
|
|
424
|
+
operation: key,
|
|
425
|
+
average: times.reduce((sum, time) => sum + time, 0) / times.length,
|
|
426
|
+
max: Math.max(...times),
|
|
427
|
+
min: Math.min(...times),
|
|
428
|
+
p95: times.sort((a, b) => a - b)[Math.floor(times.length * 0.95)]
|
|
429
|
+
}));
|
|
430
|
+
|
|
431
|
+
// Validate targets
|
|
432
|
+
stats.forEach(stat => {
|
|
433
|
+
console.log(`${stat.operation}: avg=${stat.average.toFixed(3)}ms, max=${stat.max.toFixed(3)}ms, p95=${stat.p95.toFixed(3)}ms`);
|
|
434
|
+
|
|
435
|
+
// Main targets: average under 1ms, p95 under 2ms
|
|
436
|
+
expect(stat.average).toBeLessThan(1);
|
|
437
|
+
expect(stat.p95).toBeLessThan(2);
|
|
438
|
+
expect(stat.max).toBeLessThan(5); // Conservative upper bound
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
});
|