diff --git a/.github/actions/execute-pipeline/action.yml b/.github/actions/execute-pipeline/action.yml index 55e4893bc4..50c32f7793 100644 --- a/.github/actions/execute-pipeline/action.yml +++ b/.github/actions/execute-pipeline/action.yml @@ -23,7 +23,7 @@ inputs: netversion: description: 'Net version' required: false - default: 'net9.0' + default: 'net10.0' runs: using: "composite" diff --git a/.github/scripts/docs/docs/benchmarks/index.md b/.github/scripts/docs/docs/benchmarks/index.md new file mode 100644 index 0000000000..8bfca449e7 --- /dev/null +++ b/.github/scripts/docs/docs/benchmarks/index.md @@ -0,0 +1,69 @@ +--- +title: Performance Benchmarks +description: Real-world performance comparisons between TUnit and other .NET testing frameworks +sidebar_position: 1 +--- + +# Performance Benchmarks + +:::info Last Updated +These benchmarks were automatically generated on **2025-11-11** from the latest CI run. + +**Environment:** Ubuntu Latest • .NET 10 +::: + +## šŸš€ Runtime Performance + + +--- + +## šŸ“Š Methodology + +These benchmarks compare TUnit against the most popular .NET testing frameworks: + +| Framework | Version Tested | +|-----------|----------------| +| **TUnit** | latest | +| **xUnit v3** | latest | +| **NUnit** | latest | +| **MSTest** | latest | + +### Test Scenarios + +The benchmarks measure real-world testing patterns: + +- **DataDrivenTests**: Parameterized tests with multiple data sources +- **AsyncTests**: Realistic async/await patterns with I/O simulation +- **ScaleTests**: Large test suites (150+ tests) measuring scalability +- **MatrixTests**: Combinatorial test generation and execution +- **MassiveParallelTests**: Parallel execution stress tests +- **SetupTeardownTests**: Expensive test fixtures with setup/teardown overhead + +### Environment + +- **OS**: Ubuntu Latest (GitHub Actions) +- **Runtime**: .NET 10 +- **SDK**: .NET 10 SDK +- **Hardware**: GitHub Actions Standard Runner (Ubuntu) +- **Tool**: BenchmarkDotNet + +### Why These Numbers Matter + +- **No Mocking**: All tests use realistic patterns, not artificial micro-benchmarks +- **Equivalent Logic**: Each framework implements identical test scenarios +- **Warm-Up Excluded**: Measurements exclude JIT warm-up overhead +- **Statistical Rigor**: Multiple iterations with outlier detection + +### Source Code + +All benchmark source code is available in the [`tools/speed-comparison`](https://github.com/thomhurst/TUnit/tree/main/tools/speed-comparison) directory. + +--- + +:::note Continuous Benchmarking +These benchmarks run automatically daily via [GitHub Actions](https://github.com/thomhurst/TUnit/actions/workflows/speed-comparison.yml). + +Each benchmark runs multiple iterations with statistical analysis to ensure accuracy. Results may vary based on hardware and test characteristics. +::: + +*Last generated: 2025-11-11T23:48:04.871Z* diff --git a/.github/scripts/process-benchmarks.js b/.github/scripts/process-benchmarks.js index 1a58bb5282..ecfda6f301 100644 --- a/.github/scripts/process-benchmarks.js +++ b/.github/scripts/process-benchmarks.js @@ -79,8 +79,10 @@ function extractEnvironmentInfo(content) { } function parseMeanValue(meanStr) { - // Parse "352.5 ms" -> 352.5 - const match = meanStr.match(/[\d.]+/); + // Parse "352.5 ms" or "1,211.6 ms" -> 352.5 or 1211.6 + // Remove commas, then extract number + const cleaned = meanStr.replace(/,/g, ''); + const match = cleaned.match(/[\d.]+/); return match ? parseFloat(match[0]) : 0; } @@ -136,168 +138,234 @@ const stats = { lastUpdated: new Date().toISOString() }; -console.log('\nšŸ“ˆ Calculating performance comparisons...'); - -function calculateComparisons() { - const comparisons = {}; - - Object.entries(categories.runtime).forEach(([category, data]) => { - const tunit = data.find(d => d.Method === 'TUnit'); - const tunitAOT = data.find(d => d.Method === 'TUnit_AOT'); - const xunit = data.find(d => d.Method === 'xUnit3'); - const nunit = data.find(d => d.Method === 'NUnit'); - const mstest = data.find(d => d.Method === 'MSTest'); - - if (tunit) { - const tunitMean = parseMeanValue(tunit.Mean); - comparisons[category] = { - tunitMean, - tunitAOTMean: tunitAOT ? parseMeanValue(tunitAOT.Mean) : null, - vsXUnit: xunit ? (parseMeanValue(xunit.Mean) / tunitMean).toFixed(2) : null, - vsNUnit: nunit ? (parseMeanValue(nunit.Mean) / tunitMean).toFixed(2) : null, - vsMSTest: mstest ? (parseMeanValue(mstest.Mean) / tunitMean).toFixed(2) : null, - aotSpeedup: tunitAOT ? (tunitMean / parseMeanValue(tunitAOT.Mean)).toFixed(2) : null - }; - } - }); - - return comparisons; -} - -const comparisons = calculateComparisons(); - -// Calculate average speedups -const avgSpeedups = { - vsXUnit: 0, - vsNUnit: 0, - vsMSTest: 0, - count: 0 -}; - -Object.values(comparisons).forEach(comp => { - if (comp.vsXUnit) { - avgSpeedups.vsXUnit += parseFloat(comp.vsXUnit); - avgSpeedups.count++; - } - if (comp.vsNUnit) avgSpeedups.vsNUnit += parseFloat(comp.vsNUnit); - if (comp.vsMSTest) avgSpeedups.vsMSTest += parseFloat(comp.vsMSTest); -}); - -if (avgSpeedups.count > 0) { - avgSpeedups.vsXUnit = (avgSpeedups.vsXUnit / avgSpeedups.count).toFixed(1); - avgSpeedups.vsNUnit = (avgSpeedups.vsNUnit / avgSpeedups.count).toFixed(1); - avgSpeedups.vsMSTest = (avgSpeedups.vsMSTest / avgSpeedups.count).toFixed(1); -} - -console.log(` Average speedup vs xUnit: ${avgSpeedups.vsXUnit}x`); -console.log(` Average speedup vs NUnit: ${avgSpeedups.vsNUnit}x`); -console.log(` Average speedup vs MSTest: ${avgSpeedups.vsMSTest}x`); - -// Generate main benchmarks page +console.log('\nšŸ“Š Preparing benchmark data...'); console.log('\nšŸ“ Generating documentation...'); const timestamp = new Date().toISOString().split('T')[0]; +const sampleData = Object.values(categories.runtime)[0] || []; +const frameworks = { + tunit: sampleData.find(d => d.Method === 'TUnit')?.Version || 'latest', + xunit: sampleData.find(d => d.Method === 'xUnit3')?.Version || 'latest', + nunit: sampleData.find(d => d.Method === 'NUnit')?.Version || 'latest', + mstest: sampleData.find(d => d.Method === 'MSTest')?.Version || 'latest' +}; -let mainPage = `--- -title: Performance Benchmarks -description: Real-world performance comparisons between TUnit and other .NET testing frameworks -sidebar_position: 1 +// Generate individual benchmark pages for each runtime category +Object.entries(categories.runtime).forEach(([testClass, data]) => { + const benchmarkPage = `--- +title: ${testClass} +description: Performance benchmark results for ${testClass} +sidebar_position: ${Object.keys(categories.runtime).indexOf(testClass) + 2} --- -# Performance Benchmarks +# ${testClass} Benchmark :::info Last Updated -These benchmarks were automatically generated on **${timestamp}** from the latest CI run. +This benchmark was automatically generated on **${timestamp}** from the latest CI run. **Environment:** ${environmentInfo.os || 'Ubuntu Latest'} • ${environmentInfo.sdk || '.NET 10'} ::: -## šŸŽÆ Executive Summary +## šŸ“Š Results + +| Framework | Version | Mean | Median | StdDev | +|-----------|---------|------|--------|--------| +${data.map(row => { + const name = row.Method.includes('TUnit_AOT') ? '**TUnit (AOT)**' : row.Method.includes('TUnit') ? '**TUnit**' : row.Method; + return `| ${name} | ${row.Version || 'N/A'} | ${row.Mean} | ${row.Median || 'N/A'} | ${row.StdDev || 'N/A'} |`; +}).join('\n')} + +## šŸ“ˆ Visual Comparison + +\`\`\`mermaid +%%{init: { + 'theme':'base', + 'themeVariables': { + 'primaryColor': '#10b981', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#059669', + 'lineColor': '#d1d5db', + 'secondaryColor': '#3b82f6', + 'tertiaryColor': '#f59e0b', + 'background': '#ffffff', + 'mainBkg': '#10b981', + 'secondBkg': '#ef4444', + 'tertiaryBkg': '#f59e0b' + } +}}%% +xychart-beta + title "${testClass} Performance Comparison" + x-axis [${data.map(d => `"${d.Method}"`).join(', ')}] + y-axis "Time (${data[0]?.Mean.includes(' s') ? 's' : 'ms'})" 0 --> ${Math.ceil(Math.max(...data.map(d => parseMeanValue(d.Mean))) * 1.2)} + bar [${data.map(d => parseMeanValue(d.Mean)).join(', ')}] +\`\`\` + +## šŸŽÆ Key Insights + +${(() => { + const tunitResult = data.find(d => d.Method === 'TUnit'); + const tunitAotResult = data.find(d => d.Method === 'TUnit_AOT'); + const otherResults = data.filter(d => !d.Method.includes('TUnit')); + + if (!tunitResult) return '- TUnit data not available'; + + const tunitMean = parseMeanValue(tunitResult.Mean); + const insights = []; + + otherResults.forEach(other => { + const otherMean = parseMeanValue(other.Mean); + const speedup = (otherMean / tunitMean).toFixed(2); + if (speedup > 1) { + insights.push(`- **${speedup}x faster** than ${other.Method} (${other.Version})`); + } + }); -TUnit demonstrates significant performance advantages across all testing scenarios: + if (tunitAotResult) { + const aotMean = parseMeanValue(tunitAotResult.Mean); + const aotSpeedup = (tunitMean / aotMean).toFixed(2); + insights.push(`- **${aotSpeedup}x faster** with Native AOT compilation`); + } -
+ return insights.join('\n'); +})()} -### Average Performance vs Other Frameworks +--- -- **${avgSpeedups.vsXUnit}x faster** than xUnit v3 -- **${avgSpeedups.vsNUnit}x faster** than NUnit -- **${avgSpeedups.vsMSTest}x faster** than MSTest +:::note Methodology +View the [benchmarks overview](/docs/benchmarks) for methodology details and environment information. +::: -
+*Last generated: ${new Date().toISOString()}* +`; ---- + fs.writeFileSync(path.join(OUTPUT_DIR, `${testClass}.md`), benchmarkPage); + console.log(` āœ“ Created ${OUTPUT_DIR}/${testClass}.md`); + + // Generate individual JSON file for each benchmark + const benchmarkJson = { + timestamp: new Date().toISOString(), + category: testClass, + environment: environmentInfo, + results: data + }; + + fs.writeFileSync( + path.join(STATIC_DIR, `${testClass}.json`), + JSON.stringify(benchmarkJson, null, 2) + ); + console.log(` āœ“ Created ${STATIC_DIR}/${testClass}.json`); +}); -## šŸš€ Runtime Performance +// Generate build benchmark page if available +if (Object.keys(categories.build).length > 0) { + Object.entries(categories.build).forEach(([testClass, data]) => { + const benchmarkPage = `--- +title: Build Performance +description: Compilation time benchmark results +sidebar_position: ${Object.keys(categories.runtime).length + 2} +--- -`; +# Build Performance Benchmark -// Add runtime results -Object.entries(categories.runtime).forEach(([testClass, data]) => { - const comparison = comparisons[testClass]; +:::info Last Updated +This benchmark was automatically generated on **${timestamp}** from the latest CI run. - mainPage += `\n### ${testClass}\n\n`; +**Environment:** ${environmentInfo.os || 'Ubuntu Latest'} • ${environmentInfo.sdk || '.NET 10'} +::: - if (comparison && comparison.aotSpeedup) { - mainPage += `:::tip Native AOT Performance\n`; - mainPage += `TUnit with Native AOT compilation is **${comparison.aotSpeedup}x faster** than regular JIT!\n`; - mainPage += `:::\n\n`; +## šŸ“Š Results + +Compilation time comparison across frameworks: + +| Framework | Version | Mean | Median | StdDev | +|-----------|---------|------|--------|--------| +${data.map(row => { + const name = row.Method.includes('TUnit') ? '**TUnit**' : row.Method; + return `| ${name} | ${row.Version || 'N/A'} | ${row.Mean} | ${row.Median || 'N/A'} | ${row.StdDev || 'N/A'} |`; +}).join('\n')} + +## šŸ“ˆ Visual Comparison + +\`\`\`mermaid +%%{init: { + 'theme':'base', + 'themeVariables': { + 'primaryColor': '#10b981', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#059669', + 'lineColor': '#d1d5db', + 'secondaryColor': '#3b82f6', + 'tertiaryColor': '#f59e0b', + 'background': '#ffffff', + 'mainBkg': '#10b981', + 'secondBkg': '#ef4444', + 'tertiaryBkg': '#f59e0b' } +}}%% +xychart-beta + title "Build Time Comparison" + x-axis [${data.map(d => `"${d.Method}"`).join(', ')}] + y-axis "Time (${data[0]?.Mean.includes(' s') ? 's' : 'ms'})" 0 --> ${Math.ceil(Math.max(...data.map(d => parseMeanValue(d.Mean))) * 1.2)} + bar [${data.map(d => parseMeanValue(d.Mean)).join(', ')}] +\`\`\` - // Add speedup badges - if (comparison) { - const badges = []; - if (comparison.vsXUnit) badges.push(`**${comparison.vsXUnit}x faster** than xUnit`); - if (comparison.vsNUnit) badges.push(`**${comparison.vsNUnit}x faster** than NUnit`); - if (comparison.vsMSTest) badges.push(`**${comparison.vsMSTest}x faster** than MSTest`); +--- - if (badges.length > 0) { - mainPage += `**Performance:** ${badges.join(' • ')}\n\n`; - } - } +:::note Methodology +View the [benchmarks overview](/docs/benchmarks) for methodology details and environment information. +::: - // Add table - mainPage += `| Framework | Version | Mean | Median | StdDev |\n`; - mainPage += `|-----------|---------|------|--------|--------|\n`; +*Last generated: ${new Date().toISOString()}* +`; - data.forEach(row => { - const emoji = row.Method.includes('TUnit') ? 'šŸ† ' : ''; - const name = row.Method.includes('TUnit_AOT') ? '**TUnit (AOT)**' : row.Method.includes('TUnit') ? '**TUnit**' : row.Method; - mainPage += `| ${emoji}${name} | ${row.Version || 'N/A'} | ${row.Mean} | ${row.Median || 'N/A'} | ${row.StdDev || 'N/A'} |\n`; + fs.writeFileSync(path.join(OUTPUT_DIR, 'BuildTime.md'), benchmarkPage); + console.log(` āœ“ Created ${OUTPUT_DIR}/BuildTime.md`); + + // Generate build benchmark JSON + const buildJson = { + timestamp: new Date().toISOString(), + category: 'BuildTime', + environment: environmentInfo, + results: data + }; + + fs.writeFileSync( + path.join(STATIC_DIR, 'BuildTime.json'), + JSON.stringify(buildJson, null, 2) + ); + console.log(` āœ“ Created ${STATIC_DIR}/BuildTime.json`); }); +} - mainPage += '\n'; -}); +// Generate index/overview page +const indexPage = `--- +title: Performance Benchmarks +description: Real-world performance comparisons between TUnit and other .NET testing frameworks +sidebar_position: 1 +--- -// Add build time results -if (Object.keys(categories.build).length > 0) { - mainPage += `\n---\n\n## šŸ”Ø Build Performance\n\n`; - mainPage += `Compilation time comparison across frameworks:\n\n`; +# Performance Benchmarks - Object.entries(categories.build).forEach(([testClass, data]) => { - mainPage += `| Framework | Version | Mean | Median | StdDev |\n`; - mainPage += `|-----------|---------|------|--------|--------|\n`; +:::info Last Updated +These benchmarks were automatically generated on **${timestamp}** from the latest CI run. - data.forEach(row => { - const emoji = row.Method.includes('TUnit') ? 'šŸ† ' : ''; - const name = row.Method.includes('TUnit') ? '**TUnit**' : row.Method; - mainPage += `| ${emoji}${name} | ${row.Version || 'N/A'} | ${row.Mean} | ${row.Median || 'N/A'} | ${row.StdDev || 'N/A'} |\n`; - }); +**Environment:** ${environmentInfo.os || 'Ubuntu Latest'} • ${environmentInfo.sdk || '.NET 10'} +::: - mainPage += '\n'; - }); -} +## šŸš€ Runtime Benchmarks -// Add methodology section -const sampleData = Object.values(categories.runtime)[0] || []; -const frameworks = { - tunit: sampleData.find(d => d.Method === 'TUnit')?.Version || 'latest', - xunit: sampleData.find(d => d.Method === 'xUnit3')?.Version || 'latest', - nunit: sampleData.find(d => d.Method === 'NUnit')?.Version || 'latest', - mstest: sampleData.find(d => d.Method === 'MSTest')?.Version || 'latest' -}; +Click on any benchmark to view detailed results: + +${Object.keys(categories.runtime).map(testClass => + `- [${testClass}](${testClass}) - Detailed performance analysis` +).join('\n')} + +${Object.keys(categories.build).length > 0 ? ` +## šŸ”Ø Build Benchmarks + +- [Build Performance](BuildTime) - Compilation time comparison +` : ''} -mainPage += ` --- ## šŸ“Š Methodology @@ -317,9 +385,10 @@ The benchmarks measure real-world testing patterns: - **DataDrivenTests**: Parameterized tests with multiple data sources - **AsyncTests**: Realistic async/await patterns with I/O simulation -- **ScaleTests**: Large test suites (1000+ tests) measuring scalability +- **ScaleTests**: Large test suites (150+ tests) measuring scalability - **MatrixTests**: Combinatorial test generation and execution - **MassiveParallelTests**: Parallel execution stress tests +- **SetupTeardownTests**: Expensive test fixtures with setup/teardown overhead ### Environment @@ -351,7 +420,7 @@ Each benchmark runs multiple iterations with statistical analysis to ensure accu *Last generated: ${new Date().toISOString()}* `; -fs.writeFileSync(path.join(OUTPUT_DIR, 'index.md'), mainPage); +fs.writeFileSync(path.join(OUTPUT_DIR, 'index.md'), indexPage); console.log(` āœ“ Created ${OUTPUT_DIR}/index.md`); // Generate JSON for interactive components @@ -360,8 +429,6 @@ const benchmarkData = { environment: environmentInfo, categories: categories.runtime, build: categories.build, - comparisons, - averageSpeedups: avgSpeedups, stats }; @@ -387,7 +454,6 @@ if (fs.existsSync(historicalFile)) { // Add new data point historical.push({ date: new Date().toISOString().split('T')[0], - averageSpeedups: avgSpeedups, environment: environmentInfo.os || 'Ubuntu' }); @@ -400,9 +466,30 @@ fs.writeFileSync( ); console.log(` āœ“ Updated ${historicalFile} (${historical.length} data points)`); +// Generate benchmark summary for PR body +const benchmarkSummary = { + runtime: Object.keys(categories.runtime), + build: Object.keys(categories.build), + timestamp: timestamp, + environment: `${environmentInfo.os || 'Ubuntu Latest'} • ${environmentInfo.sdk || '.NET 10'}` +}; + +fs.writeFileSync( + path.join(STATIC_DIR, 'summary.json'), + JSON.stringify(benchmarkSummary, null, 2) +); +console.log(` āœ“ Created ${STATIC_DIR}/summary.json`); + console.log('\nāœ… Benchmark processing complete!\n'); console.log(`Summary:`); console.log(` - Runtime categories: ${stats.runtimeCategories}`); console.log(` - Build categories: ${stats.buildCategories}`); console.log(` - Total benchmarks: ${stats.totalBenchmarks}`); -console.log(` - Output files: 3 (markdown + 2 JSON files)`); +console.log(` - Output files: 4 (markdown + 3 JSON files)`); +console.log(`\nšŸ“Š Benchmarks produced:`); +console.log(`\nRuntime Benchmarks:`); +Object.keys(categories.runtime).forEach(cat => console.log(` - ${cat}`)); +if (Object.keys(categories.build).length > 0) { + console.log(`\nBuild Benchmarks:`); + Object.keys(categories.build).forEach(cat => console.log(` - ${cat}`)); +} diff --git a/.github/workflows/speed-comparison.yml b/.github/workflows/speed-comparison.yml index 316ddff2d3..510e5d4f3e 100644 --- a/.github/workflows/speed-comparison.yml +++ b/.github/workflows/speed-comparison.yml @@ -45,7 +45,7 @@ jobs: environment: ${{ github.ref == 'refs/heads/main' && 'Production' || 'Pull Requests' }} strategy: matrix: - class: [DataDrivenTests, AsyncTests, ScaleTests, MatrixTests, MassiveParallelTests] + class: [DataDrivenTests, AsyncTests, ScaleTests, MatrixTests, MassiveParallelTests, SetupTeardownTests] fail-fast: false runs-on: ubuntu-latest concurrency: @@ -135,7 +135,7 @@ jobs: - uses: actions/checkout@v5 with: fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.ADMIN_TOKEN }} - name: Download All Runtime Benchmark Artifacts uses: actions/download-artifact@v6 @@ -160,6 +160,27 @@ jobs: run: | node .github/scripts/process-benchmarks.js + - name: Generate Benchmark List + id: benchmark_list + run: | + # Read the summary.json file and format it for the PR body + SUMMARY=$(cat docs/static/benchmarks/summary.json) + RUNTIME_BENCHMARKS=$(echo "$SUMMARY" | grep -A 100 '"runtime"' | grep -o '"[^"]*Tests"' | sed 's/"//g' | sed 's/^/- /' | tr '\n' '|') + BUILD_BENCHMARKS=$(echo "$SUMMARY" | grep -A 100 '"build"' | grep -o '"[^"]*"' | sed 's/"//g' | grep -v 'runtime\|build\|timestamp\|environment' | sed 's/^/- /' | tr '\n' '|') + + # Replace | with newlines for proper formatting + RUNTIME_LIST=$(echo "$RUNTIME_BENCHMARKS" | sed 's/|/\n/g') + BUILD_LIST=$(echo "$BUILD_BENCHMARKS" | sed 's/|/\n/g') + + # Set output with proper escaping + echo "runtime_benchmarks<> $GITHUB_OUTPUT + echo "$RUNTIME_LIST" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + echo "build_benchmarks<> $GITHUB_OUTPUT + echo "$BUILD_LIST" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + - name: Check for Changes id: check_changes run: | @@ -177,7 +198,7 @@ jobs: id: create_pr uses: peter-evans/create-pull-request@v7 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.ADMIN_TOKEN }} commit-message: 'chore: update benchmark results' branch: automated-benchmarks-update delete-branch: true @@ -187,10 +208,19 @@ jobs: This PR updates the benchmark documentation with the latest results from the Speed Comparison workflow. + ### Benchmarks Produced + + #### Runtime Benchmarks + ${{ steps.benchmark_list.outputs.runtime_benchmarks }} + + #### Build Benchmarks + ${{ steps.benchmark_list.outputs.build_benchmarks }} + ### Changes - Updated benchmark data in `docs/static/benchmarks/latest.json` - Updated historical trends in `docs/static/benchmarks/historical.json` - Regenerated benchmark documentation in `docs/docs/benchmarks/index.md` + - Updated benchmark summary in `docs/static/benchmarks/summary.json` ### Workflow Run - **Run ID**: ${{ github.run_id }} @@ -206,10 +236,12 @@ jobs: documentation draft: false - - name: Enable Auto-Merge + - name: Merge PR Immediately if: steps.check_changes.outputs.has_changes == 'true' && steps.create_pr.outputs.pull-request-number != '' env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.ADMIN_TOKEN }} run: | - gh pr merge ${{ steps.create_pr.outputs.pull-request-number }} --auto --squash --delete-branch + # Wait a moment for PR to be fully created + sleep 5 + gh pr merge ${{ steps.create_pr.outputs.pull-request-number }} --squash --delete-branch --admin diff --git a/Directory.Build.props b/Directory.Build.props index a351596691..3a10242347 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -69,4 +69,16 @@ - + + true + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index d5240f97bb..d4a959ae77 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,9 +16,9 @@ - - - + + + @@ -32,7 +32,7 @@ - + @@ -52,14 +52,14 @@ - + - + @@ -81,12 +81,12 @@ - - - - - - + + + + + + diff --git a/Polyfill.targets b/Polyfill.targets index 27f0006759..ca88149295 100644 --- a/Polyfill.targets +++ b/Polyfill.targets @@ -1,14 +1,6 @@ - - true - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/Roslyn.props b/Roslyn.props index 24cdff7c9e..9a3940c423 100644 --- a/Roslyn.props +++ b/Roslyn.props @@ -1,16 +1,9 @@ - - - true - + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/TUnit.Assertions.SourceGenerator.Tests/TestsBase.cs b/TUnit.Assertions.SourceGenerator.Tests/TestsBase.cs index eddc6c2fda..10df29a364 100644 --- a/TUnit.Assertions.SourceGenerator.Tests/TestsBase.cs +++ b/TUnit.Assertions.SourceGenerator.Tests/TestsBase.cs @@ -37,7 +37,7 @@ public Task RunTest(string inputFile, Func assertions) public async Task RunTest(string inputFile, RunTestOptions runTestOptions, Func assertions) { #if NET - var source = await FilePolyfill.ReadAllTextAsync(inputFile); + var source = await File.ReadAllTextAsync(inputFile); #else var source = File.ReadAllText(inputFile); #endif @@ -80,7 +80,7 @@ namespace System.Diagnostics.CodeAnalysis; public class UnconditionalSuppressMessageAttribute : Attribute; """, #if NET - ..await Task.WhenAll(runTestOptions.AdditionalFiles.Select(x => FilePolyfill.ReadAllTextAsync(x))), + ..await Task.WhenAll(runTestOptions.AdditionalFiles.Select(x => File.ReadAllTextAsync(x))), #else ..runTestOptions.AdditionalFiles.Select(x => File.ReadAllText(x)), #endif @@ -160,8 +160,8 @@ Have you added required references and additional files? verifyTask = verifyTask.OnVerifyMismatch(async (pair, message, verify) => { - var received = await FilePolyfill.ReadAllTextAsync(pair.ReceivedPath); - var verified = await FilePolyfill.ReadAllTextAsync(pair.VerifiedPath); + var received = await File.ReadAllTextAsync(pair.ReceivedPath); + var verified = await File.ReadAllTextAsync(pair.VerifiedPath); // Better diff message since original one is too large await Assert.That(Scrub(received)).IsEqualTo(Scrub(verified)); diff --git a/TUnit.Core.SourceGenerator.Tests/GenericTypeResolverTests.cs b/TUnit.Core.SourceGenerator.Tests/GenericTypeResolverTests.cs index c074eb0d5f..40b105d8fe 100644 --- a/TUnit.Core.SourceGenerator.Tests/GenericTypeResolverTests.cs +++ b/TUnit.Core.SourceGenerator.Tests/GenericTypeResolverTests.cs @@ -148,7 +148,7 @@ public void TestMethod() private async Task RunTestWithInlineSource(string source) { var tempFile = Path.GetTempFileName() + ".cs"; - await FilePolyfill.WriteAllTextAsync(tempFile, source); + await File.WriteAllTextAsync(tempFile, source); try { diff --git a/TUnit.Core.SourceGenerator.Tests/TestsBase.cs b/TUnit.Core.SourceGenerator.Tests/TestsBase.cs index 161a01beed..98e003ad13 100644 --- a/TUnit.Core.SourceGenerator.Tests/TestsBase.cs +++ b/TUnit.Core.SourceGenerator.Tests/TestsBase.cs @@ -43,7 +43,7 @@ public Task RunTest(string inputFile, Func assertions) public async Task RunTest(string inputFile, RunTestOptions runTestOptions, Func assertions) { #if NET - var source = await FilePolyfill.ReadAllTextAsync(inputFile); + var source = await File.ReadAllTextAsync(inputFile); #else var source = File.ReadAllText(inputFile); #endif @@ -86,7 +86,7 @@ namespace System.Diagnostics.CodeAnalysis; public class UnconditionalSuppressMessageAttribute : Attribute; """, #if NET - ..await Task.WhenAll(runTestOptions.AdditionalFiles.Select(x => FilePolyfill.ReadAllTextAsync(x))), + ..await Task.WhenAll(runTestOptions.AdditionalFiles.Select(x => File.ReadAllTextAsync(x))), #else ..runTestOptions.AdditionalFiles.Select(x => File.ReadAllText(x)), #endif @@ -172,8 +172,8 @@ Have you added required references and additional files? { verifyTask = verifyTask.OnVerifyMismatch(async (pair, message, verify) => { - var received = await FilePolyfill.ReadAllTextAsync(pair.ReceivedPath); - var verified = await FilePolyfill.ReadAllTextAsync(pair.VerifiedPath); + var received = await File.ReadAllTextAsync(pair.ReceivedPath); + var verified = await File.ReadAllTextAsync(pair.VerifiedPath); // Better diff message since original one is too large await Assert.That(Scrub(received)).IsEqualTo(Scrub(verified)); diff --git a/TUnit.Core.SourceGenerator.Tests/UnifiedReflectionFreeTests.cs b/TUnit.Core.SourceGenerator.Tests/UnifiedReflectionFreeTests.cs index 3a039c557d..6182181767 100644 --- a/TUnit.Core.SourceGenerator.Tests/UnifiedReflectionFreeTests.cs +++ b/TUnit.Core.SourceGenerator.Tests/UnifiedReflectionFreeTests.cs @@ -95,7 +95,7 @@ public void TestWithConfiguration() private async Task RunTestWithInlineSource(string source) { var tempFile = Path.GetTempFileName() + ".cs"; - await FilePolyfill.WriteAllTextAsync(tempFile, source); + await File.WriteAllTextAsync(tempFile, source); try { diff --git a/TUnit.Core.SourceGenerator.Tests/Verify.cs b/TUnit.Core.SourceGenerator.Tests/Verify.cs index d1db167879..d15b2ac87a 100644 --- a/TUnit.Core.SourceGenerator.Tests/Verify.cs +++ b/TUnit.Core.SourceGenerator.Tests/Verify.cs @@ -157,15 +157,15 @@ public async Task ToTask() if (!File.Exists(_verifiedPath)) { - await FilePolyfill.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); + await File.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); throw new InvalidOperationException($"No verified file found for '{name}'."); } - var approved = await FilePolyfill.ReadAllTextAsync(_verifiedPath); + var approved = await File.ReadAllTextAsync(_verifiedPath); if (!string.Equals(NormalizeNewline(final), NormalizeNewline(approved), StringComparison.Ordinal)) { - await FilePolyfill.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); + await File.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); if (_onVerifyMismatch != null) { diff --git a/TUnit.Core/Attributes/TestData/ClassDataSources.cs b/TUnit.Core/Attributes/TestData/ClassDataSources.cs index a933e860b4..efad3790cd 100644 --- a/TUnit.Core/Attributes/TestData/ClassDataSources.cs +++ b/TUnit.Core/Attributes/TestData/ClassDataSources.cs @@ -73,24 +73,21 @@ private string GetKey(int index, SharedType[] sharedTypes, string[] keys) private static object Create([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, DataGeneratorMetadata dataGeneratorMetadata) { - return CreateWithNestedDependencies(type, dataGeneratorMetadata, recursionDepth: 0); + return Create(type, dataGeneratorMetadata, recursionDepth: 0); } private const int MaxRecursionDepth = 10; - [UnconditionalSuppressMessage("Trimming", "IL2072:Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' requirements", - Justification = "PropertyType from PropertyInjectionMetadata has the required DynamicallyAccessedMembers annotations")] - private static object CreateWithNestedDependencies([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, DataGeneratorMetadata dataGeneratorMetadata, int recursionDepth) + private static object Create([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, DataGeneratorMetadata dataGeneratorMetadata, int recursionDepth) { if (recursionDepth >= MaxRecursionDepth) { throw new InvalidOperationException($"Maximum recursion depth ({MaxRecursionDepth}) exceeded when creating nested ClassDataSource dependencies. This may indicate a circular dependency."); } - object instance; try { - instance = Activator.CreateInstance(type)!; + return Activator.CreateInstance(type)!; } catch (TargetInvocationException targetInvocationException) { @@ -101,21 +98,5 @@ private static object CreateWithNestedDependencies([DynamicallyAccessedMembers(D throw; } - - // Populate nested ClassDataSource properties recursively - var propertySource = PropertySourceRegistry.GetSource(type); - if (propertySource?.ShouldInitialize == true) - { - var propertyMetadata = propertySource.GetPropertyMetadata(); - foreach (var metadata in propertyMetadata) - { - // Recursively create the property value using CreateWithNestedDependencies - // This will handle nested ClassDataSource properties - var propertyValue = CreateWithNestedDependencies(metadata.PropertyType, dataGeneratorMetadata, recursionDepth + 1); - metadata.SetProperty(instance, propertyValue); - } - } - - return instance; } } diff --git a/TUnit.Core/TUnit.Core.targets b/TUnit.Core/TUnit.Core.targets index 6dd52bbb6b..f27fabe053 100644 --- a/TUnit.Core/TUnit.Core.targets +++ b/TUnit.Core/TUnit.Core.targets @@ -8,7 +8,7 @@ - <_TUnitPolyfillVersion>8.9.1 + <_TUnitPolyfillVersion>9.0.1 <_TUnitNeedsPolyfill Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' or '$(TargetFrameworkIdentifier)' == '.NETFramework'">true diff --git a/TUnit.Engine.Tests/Attributes/SkipNetFrameworkAttribute.cs b/TUnit.Engine.Tests/Attributes/SkipNetFrameworkAttribute.cs index 8ad1fb4e2b..b8205c3ad6 100644 --- a/TUnit.Engine.Tests/Attributes/SkipNetFrameworkAttribute.cs +++ b/TUnit.Engine.Tests/Attributes/SkipNetFrameworkAttribute.cs @@ -2,7 +2,7 @@ public class SkipNetFrameworkAttribute(string reason) : SkipAttribute(reason) { - private static readonly string NetVersion = Environment.GetEnvironmentVariable("NET_VERSION") ?? "net9.0"; + private static readonly string NetVersion = Environment.GetEnvironmentVariable("NET_VERSION") ?? "net10.0"; public override Task ShouldSkip(TestRegisteredContext testRegisteredContext) { diff --git a/TUnit.Engine.Tests/InvokableTestBase.cs b/TUnit.Engine.Tests/InvokableTestBase.cs index bc20a0e4a1..1e264449bc 100644 --- a/TUnit.Engine.Tests/InvokableTestBase.cs +++ b/TUnit.Engine.Tests/InvokableTestBase.cs @@ -22,7 +22,7 @@ public static IEnumerable GetTestModes() } } - private static readonly string GetEnvironmentVariable = Environment.GetEnvironmentVariable("NET_VERSION") ?? "net9.0"; + private static readonly string GetEnvironmentVariable = Environment.GetEnvironmentVariable("NET_VERSION") ?? "net10.0"; public static bool IsNetFramework => GetEnvironmentVariable.StartsWith("net4"); diff --git a/TUnit.Engine.Tests/TUnit.Engine.Tests.csproj b/TUnit.Engine.Tests/TUnit.Engine.Tests.csproj index 4349b07740..99a1694787 100644 --- a/TUnit.Engine.Tests/TUnit.Engine.Tests.csproj +++ b/TUnit.Engine.Tests/TUnit.Engine.Tests.csproj @@ -3,7 +3,7 @@ - net9.0 + net10.0 diff --git a/TUnit.Example.Asp.Net.TestProject/TUnit.Example.Asp.Net.TestProject.csproj b/TUnit.Example.Asp.Net.TestProject/TUnit.Example.Asp.Net.TestProject.csproj index 4106a2cedb..abc7a1390f 100644 --- a/TUnit.Example.Asp.Net.TestProject/TUnit.Example.Asp.Net.TestProject.csproj +++ b/TUnit.Example.Asp.Net.TestProject/TUnit.Example.Asp.Net.TestProject.csproj @@ -3,7 +3,7 @@ - net9.0;net10.0 + net10.0 diff --git a/TUnit.Example.Asp.Net/TUnit.Example.Asp.Net.csproj b/TUnit.Example.Asp.Net/TUnit.Example.Asp.Net.csproj index 69d9f6d009..549f17e876 100644 --- a/TUnit.Example.Asp.Net/TUnit.Example.Asp.Net.csproj +++ b/TUnit.Example.Asp.Net/TUnit.Example.Asp.Net.csproj @@ -1,7 +1,7 @@ - net9.0;net10.0 + net10.0 enable enable false diff --git a/TUnit.Pipeline/Modules/Abstract/TestBaseModule.cs b/TUnit.Pipeline/Modules/Abstract/TestBaseModule.cs index 0943197e35..481e4167a3 100644 --- a/TUnit.Pipeline/Modules/Abstract/TestBaseModule.cs +++ b/TUnit.Pipeline/Modules/Abstract/TestBaseModule.cs @@ -14,7 +14,7 @@ protected virtual IEnumerable TestableFrameworks { get { - yield return "net9.0"; + yield return "net10.0"; yield return "net8.0"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) diff --git a/TUnit.Pipeline/Modules/PublishNugetTesterAOTModule.cs b/TUnit.Pipeline/Modules/PublishNugetTesterAOTModule.cs index 5bbb404429..b15f0e8a03 100644 --- a/TUnit.Pipeline/Modules/PublishNugetTesterAOTModule.cs +++ b/TUnit.Pipeline/Modules/PublishNugetTesterAOTModule.cs @@ -32,8 +32,8 @@ protected override Task ShouldSkip(IPipelineContext context) .FindFile(x => x.Name == "TUnit.NugetTester.csproj") .AssertExists(); - // Test AOT publishing for net8.0 and net9.0 - foreach (var framework in new[] { "net8.0", "net9.0" }) + // Test AOT publishing + foreach (var framework in new[] { "net8.0", "net9.0", "net10.0" }) { var result = await SubModule($"AOT-{framework}", async () => { diff --git a/TUnit.Pipeline/Modules/RunAspNetTestsModule.cs b/TUnit.Pipeline/Modules/RunAspNetTestsModule.cs index ad5ed5103e..e6c974434a 100644 --- a/TUnit.Pipeline/Modules/RunAspNetTestsModule.cs +++ b/TUnit.Pipeline/Modules/RunAspNetTestsModule.cs @@ -22,7 +22,7 @@ public class RunAspNetTestsModule : Module Project = project.Name, NoBuild = true, Configuration = Configuration.Release, - Framework = "net9.0", + Framework = "net10.0", WorkingDirectory = project.Folder!, Arguments = ["--ignore-exit-code", "8", "--hangdump", "--hangdump-filename", "hangdump.aspnet-tests.dmp", "--hangdump-timeout", "5m"], EnvironmentVariables = new Dictionary diff --git a/TUnit.Pipeline/Modules/RunEngineTestsModule.cs b/TUnit.Pipeline/Modules/RunEngineTestsModule.cs index 162ccaf06e..49a70177aa 100644 --- a/TUnit.Pipeline/Modules/RunEngineTestsModule.cs +++ b/TUnit.Pipeline/Modules/RunEngineTestsModule.cs @@ -33,7 +33,7 @@ public class RunEngineTestsModule : Module Project = project.Name, NoBuild = true, Configuration = Configuration.Release, - Framework = "net9.0", + Framework = "net10.0", WorkingDirectory = project.Folder!, Arguments = [ "--hangdump", "--hangdump-filename", $"hangdump.{Environment.OSVersion.Platform}.engine-tests.dmp", "--hangdump-timeout", "30m", diff --git a/TUnit.Pipeline/Modules/RunTemplateTestsModule.cs b/TUnit.Pipeline/Modules/RunTemplateTestsModule.cs index ad6f2384bd..6199c64f72 100644 --- a/TUnit.Pipeline/Modules/RunTemplateTestsModule.cs +++ b/TUnit.Pipeline/Modules/RunTemplateTestsModule.cs @@ -22,7 +22,7 @@ public class RunTemplateTestsModule : Module WorkingDirectory = project.Folder!, NoBuild = true, Configuration = Configuration.Release, - Framework = "net9.0", + Framework = "net10.0", Arguments = ["--", "--hangdump", "--hangdump-filename", "hangdump.template-tests.dmp", "--hangdump-timeout", "5m"], EnvironmentVariables = new Dictionary { diff --git a/TUnit.Pipeline/Modules/TestNugetPackageModule.cs b/TUnit.Pipeline/Modules/TestNugetPackageModule.cs index 6ace295308..e9045d5c6e 100644 --- a/TUnit.Pipeline/Modules/TestNugetPackageModule.cs +++ b/TUnit.Pipeline/Modules/TestNugetPackageModule.cs @@ -37,7 +37,7 @@ protected override IEnumerable TestableFrameworks { get { - yield return "net9.0"; + yield return "net10.0"; yield return "net8.0"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) diff --git a/TUnit.PublicAPI/Tests.cs b/TUnit.PublicAPI/Tests.cs index 0aa7f2dff9..67830f80f0 100644 --- a/TUnit.PublicAPI/Tests.cs +++ b/TUnit.PublicAPI/Tests.cs @@ -51,8 +51,8 @@ await VerifyTUnit.Verify(publicApi) .ScrubFilePaths() .OnVerifyMismatch(async (pair, message, verify) => { - var received = await FilePolyfill.ReadAllTextAsync(pair.ReceivedPath); - var verified = await FilePolyfill.ReadAllTextAsync(pair.VerifiedPath); + var received = await File.ReadAllTextAsync(pair.ReceivedPath); + var verified = await File.ReadAllTextAsync(pair.VerifiedPath); // Better diff message since original one is too large await Assert.That(Scrub(received)).IsEqualTo(Scrub(verified)); diff --git a/TUnit.PublicAPI/Verify.cs b/TUnit.PublicAPI/Verify.cs index d057db9a0b..5059fc603c 100644 --- a/TUnit.PublicAPI/Verify.cs +++ b/TUnit.PublicAPI/Verify.cs @@ -129,15 +129,15 @@ public async Task ToTask() if (!File.Exists(_verifiedPath)) { - await FilePolyfill.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); + await File.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); throw new InvalidOperationException($"No verified file found for '{name}'."); } - var approved = await FilePolyfill.ReadAllTextAsync(_verifiedPath); + var approved = await File.ReadAllTextAsync(_verifiedPath); if (!string.Equals(NormalizeNewline(final), NormalizeNewline(approved), StringComparison.Ordinal)) { - await FilePolyfill.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); + await File.WriteAllTextAsync(_receivedPath, NormalizeNewline(final)); if (_onVerifyMismatch != null) { diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/TUnit.AspNet/TUnit.AspNet.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/TUnit.AspNet/TUnit.AspNet.csproj index 8967721da8..eb10888b9e 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/TUnit.AspNet/TUnit.AspNet.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/TUnit.AspNet/TUnit.AspNet.csproj @@ -4,7 +4,7 @@ enable enable Exe - net9.0 + net10.0 diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/WebApp/WebApp.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/WebApp/WebApp.csproj index 0fb72c4b20..a6a96dcf18 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/WebApp/WebApp.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.AspNet._.verified/TUnit.AspNet/WebApp/WebApp.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ApiService/TUnit.Aspire.Starter.ApiService.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ApiService/TUnit.Aspire.Starter.ApiService.csproj index 0cdcf8be70..1ad71b0e28 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ApiService/TUnit.Aspire.Starter.ApiService.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ApiService/TUnit.Aspire.Starter.ApiService.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.AppHost/TUnit.Aspire.Starter.AppHost.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.AppHost/TUnit.Aspire.Starter.AppHost.csproj index 18012ac870..3cbe117a5a 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.AppHost/TUnit.Aspire.Starter.AppHost.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.AppHost/TUnit.Aspire.Starter.AppHost.csproj @@ -4,7 +4,7 @@ Exe - net9.0 + net10.0 enable enable true diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ServiceDefaults/TUnit.Aspire.Starter.ServiceDefaults.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ServiceDefaults/TUnit.Aspire.Starter.ServiceDefaults.csproj index 6b09c19d12..f0593381b8 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ServiceDefaults/TUnit.Aspire.Starter.ServiceDefaults.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.ServiceDefaults/TUnit.Aspire.Starter.ServiceDefaults.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable true diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.TestProject/TUnit.Aspire.Starter.TestProject.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.TestProject/TUnit.Aspire.Starter.TestProject.csproj index 2356fbfa25..241b9eb367 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.TestProject/TUnit.Aspire.Starter.TestProject.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.TestProject/TUnit.Aspire.Starter.TestProject.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable false diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.WebApp/TUnit.Aspire.Starter.WebApp.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.WebApp/TUnit.Aspire.Starter.WebApp.csproj index ddb4c3bf05..d871db6526 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.WebApp/TUnit.Aspire.Starter.WebApp.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Starter._.verified/TUnit.Aspire.Starter/TUnit.Aspire.Starter.WebApp/TUnit.Aspire.Starter.WebApp.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Test._.verified/TUnit.Aspire.Test/TUnit.Aspire.Test.csproj b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Test._.verified/TUnit.Aspire.Test/TUnit.Aspire.Test.csproj index 3606790ad9..3646299f7b 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Test._.verified/TUnit.Aspire.Test/TUnit.Aspire.Test.csproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTest.TUnit.Aspire.Test._.verified/TUnit.Aspire.Test/TUnit.Aspire.Test.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable false diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp.fsproj b/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp.fsproj index be7d8a2c0d..30cbfc590b 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp.fsproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp/TUnit.AspNet.FSharp.fsproj @@ -5,7 +5,7 @@ enable enable Exe - net9.0 + net10.0 diff --git a/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj b/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj index 4018f042a6..5393f5177d 100644 --- a/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj +++ b/TUnit.Templates.Tests/Snapshots/InstantiationTestWithFSharp.TUnit.AspNet.FSharp._.verified/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 diff --git a/TUnit.Templates.Tests/TUnit.Templates.Tests.csproj b/TUnit.Templates.Tests/TUnit.Templates.Tests.csproj index bfa9211dda..2868a34ab1 100644 --- a/TUnit.Templates.Tests/TUnit.Templates.Tests.csproj +++ b/TUnit.Templates.Tests/TUnit.Templates.Tests.csproj @@ -3,7 +3,7 @@ - net9.0;net10.0 + net10.0 diff --git a/TUnit.Templates/TUnit.Templates.csproj b/TUnit.Templates/TUnit.Templates.csproj index f5fea84539..97c688cbf6 100644 --- a/TUnit.Templates/TUnit.Templates.csproj +++ b/TUnit.Templates/TUnit.Templates.csproj @@ -10,7 +10,7 @@ https://www.github.com/thomhurst/TUnit Template - net9.0 + net10.0 true false content diff --git a/TUnit.Templates/content/TUnit.AspNet.FSharp/TestProject/TestProject.fsproj b/TUnit.Templates/content/TUnit.AspNet.FSharp/TestProject/TestProject.fsproj index f1ba496a75..04588b29e1 100644 --- a/TUnit.Templates/content/TUnit.AspNet.FSharp/TestProject/TestProject.fsproj +++ b/TUnit.Templates/content/TUnit.AspNet.FSharp/TestProject/TestProject.fsproj @@ -5,13 +5,13 @@ enable enable Exe - net9.0 + net10.0 - - - + + + diff --git a/TUnit.Templates/content/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj b/TUnit.Templates/content/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj index b42e1e3d59..e010c79135 100644 --- a/TUnit.Templates/content/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj +++ b/TUnit.Templates/content/TUnit.AspNet.FSharp/WebApp/WebApp.fsproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 diff --git a/TUnit.Templates/content/TUnit.AspNet/TestProject/TestProject.csproj b/TUnit.Templates/content/TUnit.AspNet/TestProject/TestProject.csproj index 287051cd44..f47a1018ad 100644 --- a/TUnit.Templates/content/TUnit.AspNet/TestProject/TestProject.csproj +++ b/TUnit.Templates/content/TUnit.AspNet/TestProject/TestProject.csproj @@ -4,12 +4,12 @@ enable enable Exe - net9.0 + net10.0 - - + + diff --git a/TUnit.Templates/content/TUnit.AspNet/WebApp/WebApp.csproj b/TUnit.Templates/content/TUnit.AspNet/WebApp/WebApp.csproj index d77de3aded..d1fadfb3ce 100644 --- a/TUnit.Templates/content/TUnit.AspNet/WebApp/WebApp.csproj +++ b/TUnit.Templates/content/TUnit.AspNet/WebApp/WebApp.csproj @@ -1,13 +1,13 @@  - net9.0 + net10.0 enable enable - + diff --git a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ApiService/ExampleNamespace.ApiService.csproj b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ApiService/ExampleNamespace.ApiService.csproj index b48bfef63c..e3c1bc99c1 100644 --- a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ApiService/ExampleNamespace.ApiService.csproj +++ b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ApiService/ExampleNamespace.ApiService.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable diff --git a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.AppHost/ExampleNamespace.AppHost.csproj b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.AppHost/ExampleNamespace.AppHost.csproj index a712d7c89c..44bd877374 100644 --- a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.AppHost/ExampleNamespace.AppHost.csproj +++ b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.AppHost/ExampleNamespace.AppHost.csproj @@ -4,7 +4,7 @@ Exe - net9.0 + net10.0 enable enable true diff --git a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ServiceDefaults/ExampleNamespace.ServiceDefaults.csproj b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ServiceDefaults/ExampleNamespace.ServiceDefaults.csproj index 8fd483346a..6e350de0e8 100644 --- a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ServiceDefaults/ExampleNamespace.ServiceDefaults.csproj +++ b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.ServiceDefaults/ExampleNamespace.ServiceDefaults.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable true @@ -12,8 +12,8 @@ - - + + diff --git a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.TestProject/ExampleNamespace.TestProject.csproj b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.TestProject/ExampleNamespace.TestProject.csproj index 3075c21f6c..a92efa13aa 100644 --- a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.TestProject/ExampleNamespace.TestProject.csproj +++ b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.TestProject/ExampleNamespace.TestProject.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable false @@ -11,7 +11,7 @@ - + diff --git a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.WebApp/ExampleNamespace.WebApp.csproj b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.WebApp/ExampleNamespace.WebApp.csproj index 55567ede91..3d403305bb 100644 --- a/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.WebApp/ExampleNamespace.WebApp.csproj +++ b/TUnit.Templates/content/TUnit.Aspire.Starter/ExampleNamespace.WebApp/ExampleNamespace.WebApp.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable diff --git a/TUnit.Templates/content/TUnit.Aspire.Test/ExampleNamespace.csproj b/TUnit.Templates/content/TUnit.Aspire.Test/ExampleNamespace.csproj index 7da16ebe3d..c73e63b202 100644 --- a/TUnit.Templates/content/TUnit.Aspire.Test/ExampleNamespace.csproj +++ b/TUnit.Templates/content/TUnit.Aspire.Test/ExampleNamespace.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable false @@ -10,7 +10,7 @@ - + diff --git a/TUnit.Templates/content/TUnit.FSharp/TestProject.fsproj b/TUnit.Templates/content/TUnit.FSharp/TestProject.fsproj index 87db30ee23..d1f6d6dfed 100644 --- a/TUnit.Templates/content/TUnit.FSharp/TestProject.fsproj +++ b/TUnit.Templates/content/TUnit.FSharp/TestProject.fsproj @@ -10,8 +10,8 @@ - - + + diff --git a/TUnit.Templates/content/TUnit.Playwright/TestProject.csproj b/TUnit.Templates/content/TUnit.Playwright/TestProject.csproj index 25055774d9..5f8bef5d2a 100644 --- a/TUnit.Templates/content/TUnit.Playwright/TestProject.csproj +++ b/TUnit.Templates/content/TUnit.Playwright/TestProject.csproj @@ -8,7 +8,7 @@ - + diff --git a/TUnit.Templates/content/TUnit.VB/TestProject.vbproj b/TUnit.Templates/content/TUnit.VB/TestProject.vbproj index ff5e5de922..142edd7810 100644 --- a/TUnit.Templates/content/TUnit.VB/TestProject.vbproj +++ b/TUnit.Templates/content/TUnit.VB/TestProject.vbproj @@ -8,6 +8,6 @@ - + diff --git a/TUnit.Templates/content/TUnit/TestProject.csproj b/TUnit.Templates/content/TUnit/TestProject.csproj index c375f81c6f..948ae0ad1f 100644 --- a/TUnit.Templates/content/TUnit/TestProject.csproj +++ b/TUnit.Templates/content/TUnit/TestProject.csproj @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/TUnit.TestProject.Library/Polyfills/ModuleInitializerAttribute.cs b/TUnit.TestProject.Library/Polyfills/ModuleInitializerAttribute.cs deleted file mode 100644 index 49cce8f4f0..0000000000 --- a/TUnit.TestProject.Library/Polyfills/ModuleInitializerAttribute.cs +++ /dev/null @@ -1,5 +0,0 @@ -// ReSharper disable once CheckNamespace -namespace System.Runtime.CompilerServices; - -// ReSharper disable once RedundantExtendsListEntry -sealed class ModuleInitializerAttribute : Attribute; diff --git a/TUnit.TestProject/AfterTestAttributeTests.cs b/TUnit.TestProject/AfterTestAttributeTests.cs index 47e9022801..4aba172d1d 100644 --- a/TUnit.TestProject/AfterTestAttributeTests.cs +++ b/TUnit.TestProject/AfterTestAttributeTests.cs @@ -19,7 +19,7 @@ public async ValueTask OnTestEnd(TestContext testContext) { Console.WriteLine(@"Writing file inside WriteFileAfterTestAttribute!"); - await FilePolyfill.WriteAllTextAsync(Filename, "Foo!"); + await File.WriteAllTextAsync(Filename, "Foo!"); } public int Order => 0; diff --git a/TUnit.TestProject/AfterTests/TestDiscoveryAfterTests.cs b/TUnit.TestProject/AfterTests/TestDiscoveryAfterTests.cs index 9a7b82e62a..1adac76180 100644 --- a/TUnit.TestProject/AfterTests/TestDiscoveryAfterTests.cs +++ b/TUnit.TestProject/AfterTests/TestDiscoveryAfterTests.cs @@ -11,7 +11,7 @@ public static async Task AfterTestDiscovery(TestDiscoveryContext context) [AfterEvery(TestDiscovery)] public static async Task AfterEveryTestDiscovery(TestDiscoveryContext context) { - await FilePolyfill.WriteAllTextAsync($"TestDiscoveryAfterTests{Guid.NewGuid():N}.txt", $"{context.AllTests.Count()} tests found"); + await File.WriteAllTextAsync($"TestDiscoveryAfterTests{Guid.NewGuid():N}.txt", $"{context.AllTests.Count()} tests found"); var test = context.AllTests.FirstOrDefault(x => x.Metadata.TestDetails.TestName == nameof(TestDiscoveryAfterTests.EnsureAfterEveryTestDiscoveryHit)); diff --git a/TUnit.TestProject/AfterTests/TestSessionAfterTests.cs b/TUnit.TestProject/AfterTests/TestSessionAfterTests.cs index 384c5f3ba2..34dc0788fb 100644 --- a/TUnit.TestProject/AfterTests/TestSessionAfterTests.cs +++ b/TUnit.TestProject/AfterTests/TestSessionAfterTests.cs @@ -11,7 +11,7 @@ public static async Task AfterTestSession(TestSessionContext context) [AfterEvery(TestSession)] public static async Task AfterEveryTestSession(TestSessionContext context) { - await FilePolyfill.WriteAllTextAsync($"TestSessionAfterTests{Guid.NewGuid():N}.txt", $"{context.AllTests.Count()} tests in session"); + await File.WriteAllTextAsync($"TestSessionAfterTests{Guid.NewGuid():N}.txt", $"{context.AllTests.Count()} tests in session"); var test = context.AllTests.FirstOrDefault(x => x.Metadata.TestDetails.TestName == nameof(TestSessionAfterTests.PepareForAfterSession)); diff --git a/TUnit.TestProject/BeforeTests/TestDiscoveryBeforeTests.cs b/TUnit.TestProject/BeforeTests/TestDiscoveryBeforeTests.cs index da3412f221..73b5060e00 100644 --- a/TUnit.TestProject/BeforeTests/TestDiscoveryBeforeTests.cs +++ b/TUnit.TestProject/BeforeTests/TestDiscoveryBeforeTests.cs @@ -11,7 +11,7 @@ public static async Task BeforeTestDiscovery(BeforeTestDiscoveryContext context) [BeforeEvery(TestDiscovery)] public static async Task BeforeEveryTestDiscovery(BeforeTestDiscoveryContext context) { - await FilePolyfill.WriteAllTextAsync($"TestDiscoveryBeforeTests{Guid.NewGuid():N}.txt", $"Blah!"); + await File.WriteAllTextAsync($"TestDiscoveryBeforeTests{Guid.NewGuid():N}.txt", $"Blah!"); } } diff --git a/TUnit.TestProject/BeforeTests/TestSessionBeforeTests.cs b/TUnit.TestProject/BeforeTests/TestSessionBeforeTests.cs index 8c443ef421..8baf92eadd 100644 --- a/TUnit.TestProject/BeforeTests/TestSessionBeforeTests.cs +++ b/TUnit.TestProject/BeforeTests/TestSessionBeforeTests.cs @@ -11,7 +11,7 @@ public static async Task BeforeTestSession(TestSessionContext context) [BeforeEvery(TestSession)] public static async Task BeforeEveryTestSession(TestSessionContext context) { - await FilePolyfill.WriteAllTextAsync($"TestSessionBeforeTests{Guid.NewGuid():N}.txt", $"{context.AllTests.Count()} tests in session"); + await File.WriteAllTextAsync($"TestSessionBeforeTests{Guid.NewGuid():N}.txt", $"{context.AllTests.Count()} tests in session"); var test = context.AllTests.FirstOrDefault(x => x.Metadata.TestDetails.TestName == nameof(TestSessionBeforeTests.EnsureBeforeEveryTestSessionHit)); diff --git a/TUnit.TestProject/Bugs/3803/TestRabbitContainer.cs b/TUnit.TestProject/Bugs/3803/TestRabbitContainer.cs new file mode 100644 index 0000000000..58c1a14622 --- /dev/null +++ b/TUnit.TestProject/Bugs/3803/TestRabbitContainer.cs @@ -0,0 +1,51 @@ +using TUnit.Core.Interfaces; + +namespace TUnit.TestProject.Bugs._3803; + +/// +/// Simulates a RabbitMQ test container. +/// This class should be instantiated only once per test session when marked as SharedType.PerTestSession. +/// +public class TestRabbitContainer : IAsyncInitializer, IAsyncDisposable +{ + private static int _instanceCount = 0; + private static int _initializeCount = 0; + private static int _disposeCount = 0; + + public static int InstanceCount => _instanceCount; + public static int InitializeCount => _initializeCount; + public static int DisposeCount => _disposeCount; + + public int InstanceId { get; } + public bool IsInitialized { get; private set; } + public bool IsDisposed { get; private set; } + + public TestRabbitContainer() + { + InstanceId = Interlocked.Increment(ref _instanceCount); + Console.WriteLine($"[TestRabbitContainer] Constructor called - Instance #{InstanceId}"); + } + + public Task InitializeAsync() + { + Interlocked.Increment(ref _initializeCount); + IsInitialized = true; + Console.WriteLine($"[TestRabbitContainer] InitializeAsync called - Instance #{InstanceId}"); + return Task.CompletedTask; + } + + public ValueTask DisposeAsync() + { + Interlocked.Increment(ref _disposeCount); + IsDisposed = true; + Console.WriteLine($"[TestRabbitContainer] DisposeAsync called - Instance #{InstanceId}"); + return default; + } + + public static void ResetCounters() + { + _instanceCount = 0; + _initializeCount = 0; + _disposeCount = 0; + } +} diff --git a/TUnit.TestProject/Bugs/3803/TestSqlContainer.cs b/TUnit.TestProject/Bugs/3803/TestSqlContainer.cs new file mode 100644 index 0000000000..57c6f317db --- /dev/null +++ b/TUnit.TestProject/Bugs/3803/TestSqlContainer.cs @@ -0,0 +1,51 @@ +using TUnit.Core.Interfaces; + +namespace TUnit.TestProject.Bugs._3803; + +/// +/// Simulates a SQL test container. +/// This class should be instantiated only once per test session when marked as SharedType.PerTestSession. +/// +public class TestSqlContainer : IAsyncInitializer, IAsyncDisposable +{ + private static int _instanceCount = 0; + private static int _initializeCount = 0; + private static int _disposeCount = 0; + + public static int InstanceCount => _instanceCount; + public static int InitializeCount => _initializeCount; + public static int DisposeCount => _disposeCount; + + public int InstanceId { get; } + public bool IsInitialized { get; private set; } + public bool IsDisposed { get; private set; } + + public TestSqlContainer() + { + InstanceId = Interlocked.Increment(ref _instanceCount); + Console.WriteLine($"[TestSqlContainer] Constructor called - Instance #{InstanceId}"); + } + + public Task InitializeAsync() + { + Interlocked.Increment(ref _initializeCount); + IsInitialized = true; + Console.WriteLine($"[TestSqlContainer] InitializeAsync called - Instance #{InstanceId}"); + return Task.CompletedTask; + } + + public ValueTask DisposeAsync() + { + Interlocked.Increment(ref _disposeCount); + IsDisposed = true; + Console.WriteLine($"[TestSqlContainer] DisposeAsync called - Instance #{InstanceId}"); + return default; + } + + public static void ResetCounters() + { + _instanceCount = 0; + _initializeCount = 0; + _disposeCount = 0; + } +} diff --git a/TUnit.TestProject/Bugs/3803/Tests.cs b/TUnit.TestProject/Bugs/3803/Tests.cs new file mode 100644 index 0000000000..556c173d52 --- /dev/null +++ b/TUnit.TestProject/Bugs/3803/Tests.cs @@ -0,0 +1,135 @@ +using TUnit.TestProject.Attributes; + +namespace TUnit.TestProject.Bugs._3803; + +/// +/// Bug #3803: Nested dependencies with SharedType.PerTestSession are instantiated multiple times +/// +/// Expected behavior: +/// - TestRabbitContainer should be instantiated ONCE per test session (InstanceCount == 1) +/// - TestSqlContainer should be instantiated ONCE per test session (InstanceCount == 1) +/// - All WebApplicationFactory instances should receive the SAME container instances +/// +/// Actual behavior (BUG): +/// - Containers are instantiated multiple times (once per test or once per factory) +/// - Each WebApplicationFactory receives DIFFERENT container instances +/// + +[NotInParallel] +[EngineTest(ExpectedResult.Pass)] +public class Bug3803_TestClass1 +{ + [ClassDataSource(Shared = SharedType.PerTestSession)] + public required WebApplicationFactory Factory { get; init; } + + [Test] + public async Task Test1_VerifyContainersAreShared() + { + Console.WriteLine($"[Bug3803_TestClass1.Test1] Factory Instance: #{Factory.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass1.Test1] RabbitContainer Instance: #{Factory.RabbitContainer.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass1.Test1] SqlContainer Instance: #{Factory.SqlContainer.InstanceId}"); + + // Verify containers are initialized + await Assert.That(Factory.RabbitContainer.IsInitialized).IsTrue(); + await Assert.That(Factory.SqlContainer.IsInitialized).IsTrue(); + + // BUG VERIFICATION: These should ALWAYS be 1 if SharedType.PerTestSession works correctly + await Assert.That(TestRabbitContainer.InstanceCount).IsEqualTo(1); + await Assert.That(TestSqlContainer.InstanceCount).IsEqualTo(1); + + // All instances should have ID = 1 (first and only instance) + await Assert.That(Factory.RabbitContainer.InstanceId).IsEqualTo(1); + await Assert.That(Factory.SqlContainer.InstanceId).IsEqualTo(1); + } + + [Test] + public async Task Test2_VerifyContainersAreStillShared() + { + Console.WriteLine($"[Bug3803_TestClass1.Test2] Factory Instance: #{Factory.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass1.Test2] RabbitContainer Instance: #{Factory.RabbitContainer.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass1.Test2] SqlContainer Instance: #{Factory.SqlContainer.InstanceId}"); + + // Same assertions as Test1 - containers should still be the same instances + await Assert.That(TestRabbitContainer.InstanceCount).IsEqualTo(1); + await Assert.That(TestSqlContainer.InstanceCount).IsEqualTo(1); + await Assert.That(Factory.RabbitContainer.InstanceId).IsEqualTo(1); + await Assert.That(Factory.SqlContainer.InstanceId).IsEqualTo(1); + } + + [Test] + public async Task Test3_VerifyInitializationCalledOnce() + { + Console.WriteLine($"[Bug3803_TestClass1.Test3] RabbitContainer InitializeCount: {TestRabbitContainer.InitializeCount}"); + Console.WriteLine($"[Bug3803_TestClass1.Test3] SqlContainer InitializeCount: {TestSqlContainer.InitializeCount}"); + + // Initialize should be called only once per container + await Assert.That(TestRabbitContainer.InitializeCount).IsEqualTo(1); + await Assert.That(TestSqlContainer.InitializeCount).IsEqualTo(1); + } +} + +[NotInParallel] +[EngineTest(ExpectedResult.Pass)] +public class Bug3803_TestClass2 +{ + [ClassDataSource(Shared = SharedType.PerTestSession)] + public required WebApplicationFactory Factory { get; init; } + + [Test] + public async Task Test1_DifferentClassShouldGetSameContainers() + { + Console.WriteLine($"[Bug3803_TestClass2.Test1] Factory Instance: #{Factory.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass2.Test1] RabbitContainer Instance: #{Factory.RabbitContainer.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass2.Test1] SqlContainer Instance: #{Factory.SqlContainer.InstanceId}"); + + // Even in a different test class, we should get the SAME container instances + await Assert.That(TestRabbitContainer.InstanceCount).IsEqualTo(1); + await Assert.That(TestSqlContainer.InstanceCount).IsEqualTo(1); + + // Should be the same instance (ID = 1) + await Assert.That(Factory.RabbitContainer.InstanceId).IsEqualTo(1); + await Assert.That(Factory.SqlContainer.InstanceId).IsEqualTo(1); + } + + [Test] + public async Task Test2_VerifyContainersAreInitialized() + { + await Assert.That(Factory.RabbitContainer.IsInitialized).IsTrue(); + await Assert.That(Factory.SqlContainer.IsInitialized).IsTrue(); + } +} + +[NotInParallel] +[EngineTest(ExpectedResult.Pass)] +public class Bug3803_TestClass3 +{ + [ClassDataSource(Shared = SharedType.PerTestSession)] + public required WebApplicationFactory Factory { get; init; } + + [Test] + public async Task Test1_ThirdClassAlsoGetsSameContainers() + { + Console.WriteLine($"[Bug3803_TestClass3.Test1] Factory Instance: #{Factory.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass3.Test1] RabbitContainer Instance: #{Factory.RabbitContainer.InstanceId}"); + Console.WriteLine($"[Bug3803_TestClass3.Test1] SqlContainer Instance: #{Factory.SqlContainer.InstanceId}"); + + // Still the same instances + await Assert.That(TestRabbitContainer.InstanceCount).IsEqualTo(1); + await Assert.That(TestSqlContainer.InstanceCount).IsEqualTo(1); + await Assert.That(Factory.RabbitContainer.InstanceId).IsEqualTo(1); + await Assert.That(Factory.SqlContainer.InstanceId).IsEqualTo(1); + } + + [Test] + public async Task Test2_FinalVerification() + { + Console.WriteLine($"[Bug3803_TestClass3.Test2] Final verification"); + Console.WriteLine($" Total RabbitContainer instances: {TestRabbitContainer.InstanceCount}"); + Console.WriteLine($" Total SqlContainer instances: {TestSqlContainer.InstanceCount}"); + Console.WriteLine($" Total WebApplicationFactory instances: {WebApplicationFactory.InstanceCount}"); + + // Final assertion: containers should have been instantiated exactly once + await Assert.That(TestRabbitContainer.InstanceCount).IsEqualTo(1); + await Assert.That(TestSqlContainer.InstanceCount).IsEqualTo(1); + } +} diff --git a/TUnit.TestProject/Bugs/3803/WebApplicationFactory.cs b/TUnit.TestProject/Bugs/3803/WebApplicationFactory.cs new file mode 100644 index 0000000000..3172f4d792 --- /dev/null +++ b/TUnit.TestProject/Bugs/3803/WebApplicationFactory.cs @@ -0,0 +1,61 @@ +using TUnit.Core.Interfaces; + +namespace TUnit.TestProject.Bugs._3803; + +/// +/// Simulates a WebApplicationFactory that depends on test containers. +/// The containers should be shared (SharedType.PerTestSession), meaning: +/// - Each container should be instantiated only ONCE per test session +/// - All instances of WebApplicationFactory should receive the SAME container instances +/// +public class WebApplicationFactory : IAsyncInitializer, IAsyncDisposable +{ + private static int _instanceCount = 0; + private static int _initializeCount = 0; + private static int _disposeCount = 0; + + public static int InstanceCount => _instanceCount; + public static int InitializeCount => _initializeCount; + public static int DisposeCount => _disposeCount; + + public int InstanceId { get; } + public bool IsInitialized { get; private set; } + public bool IsDisposed { get; private set; } + + [ClassDataSource(Shared = SharedType.PerTestSession)] + public required TestRabbitContainer RabbitContainer { get; init; } + + [ClassDataSource(Shared = SharedType.PerTestSession)] + public required TestSqlContainer SqlContainer { get; init; } + + public WebApplicationFactory() + { + InstanceId = Interlocked.Increment(ref _instanceCount); + Console.WriteLine($"[WebApplicationFactory] Constructor called - Instance #{InstanceId}"); + } + + public Task InitializeAsync() + { + Interlocked.Increment(ref _initializeCount); + IsInitialized = true; + Console.WriteLine($"[WebApplicationFactory] InitializeAsync called - Instance #{InstanceId}"); + Console.WriteLine($" -> RabbitContainer Instance: #{RabbitContainer.InstanceId}"); + Console.WriteLine($" -> SqlContainer Instance: #{SqlContainer.InstanceId}"); + return Task.CompletedTask; + } + + public ValueTask DisposeAsync() + { + Interlocked.Increment(ref _disposeCount); + IsDisposed = true; + Console.WriteLine($"[WebApplicationFactory] DisposeAsync called - Instance #{InstanceId}"); + return default; + } + + public static void ResetCounters() + { + _instanceCount = 0; + _initializeCount = 0; + _disposeCount = 0; + } +} diff --git a/docs/docs/benchmarks/BuildTime.md b/docs/docs/benchmarks/BuildTime.md new file mode 100644 index 0000000000..4a20e0cb3f --- /dev/null +++ b/docs/docs/benchmarks/BuildTime.md @@ -0,0 +1,57 @@ +--- +title: Build Performance +description: Compilation time benchmark results +sidebar_position: 3 +--- + +# Build Performance Benchmark + +:::info Last Updated +This benchmark was automatically generated on **2025-11-12** from the latest CI run. + +**Environment:** Ubuntu Latest • .NET SDK 10.0.100 +::: + +## šŸ“Š Results + +Compilation time comparison across frameworks: + +| Framework | Version | Mean | Median | StdDev | +|-----------|---------|------|--------|--------| +| **TUnit** | 1.0.78 | 2.061 s | 2.060 s | 0.0202 s | +| Build_NUnit | 4.4.0 | 1.645 s | 1.645 s | 0.0147 s | +| Build_MSTest | 4.0.2 | 1.712 s | 1.710 s | 0.0132 s | +| Build_xUnit3 | 3.2.0 | 1.615 s | 1.619 s | 0.0149 s | + +## šŸ“ˆ Visual Comparison + +```mermaid +%%{init: { + 'theme':'base', + 'themeVariables': { + 'primaryColor': '#10b981', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#059669', + 'lineColor': '#d1d5db', + 'secondaryColor': '#3b82f6', + 'tertiaryColor': '#f59e0b', + 'background': '#ffffff', + 'mainBkg': '#10b981', + 'secondBkg': '#ef4444', + 'tertiaryBkg': '#f59e0b' + } +}}%% +xychart-beta + title "Build Time Comparison" + x-axis ["Build_TUnit", "Build_NUnit", "Build_MSTest", "Build_xUnit3"] + y-axis "Time (s)" 0 --> 3 + bar [2.061, 1.645, 1.712, 1.615] +``` + +--- + +:::note Methodology +View the [benchmarks overview](/docs/benchmarks) for methodology details and environment information. +::: + +*Last generated: 2025-11-12T00:44:12.201Z* diff --git a/docs/docs/benchmarks/index.md b/docs/docs/benchmarks/index.md index 2c5b59a725..4795f4d795 100644 --- a/docs/docs/benchmarks/index.md +++ b/docs/docs/benchmarks/index.md @@ -7,59 +7,21 @@ sidebar_position: 1 # Performance Benchmarks :::info Last Updated -These benchmarks were automatically generated on **2025-11-10** from the latest CI run. +These benchmarks were automatically generated on **2025-11-12** from the latest CI run. -**Environment:** Ubuntu Latest • .NET SDK 10.0.100-rc.2.25502.107 +**Environment:** Ubuntu Latest • .NET SDK 10.0.100 ::: -## šŸŽÆ Executive Summary +## šŸš€ Runtime Benchmarks -TUnit demonstrates significant performance advantages across all testing scenarios: +Click on any benchmark to view detailed results: -
+- [results](results) - Detailed performance analysis -### Average Performance vs Other Frameworks -- **1.2x faster** than xUnit v3 -- **1.2x faster** than NUnit -- **1.0x faster** than MSTest +## šŸ”Ø Build Benchmarks -
- ---- - -## šŸš€ Runtime Performance - - -### results - -:::tip Native AOT Performance -TUnit with Native AOT compilation is **11.22x faster** than regular JIT! -::: - -**Performance:** **1.19x faster** than xUnit • **1.17x faster** than NUnit • **1.00x faster** than MSTest - -| Framework | Version | Mean | Median | StdDev | -|-----------|---------|------|--------|--------| -| šŸ† **TUnit** | 1.0.39 | 495.43 ms | 495.43 ms | 2.042 ms | -| NUnit | 4.4.0 | 578.77 ms | 580.83 ms | 7.718 ms | -| MSTest | 4.0.1 | 495.62 ms | 496.03 ms | 6.128 ms | -| xUnit3 | 3.2.0 | 591.61 ms | 591.28 ms | 9.984 ms | -| šŸ† **TUnit (AOT)** | 1.0.39 | 44.15 ms | 44.00 ms | 3.244 ms | - - ---- - -## šŸ”Ø Build Performance - -Compilation time comparison across frameworks: - -| Framework | Version | Mean | Median | StdDev | -|-----------|---------|------|--------|--------| -| šŸ† **TUnit** | 1.0.39 | 1.788 s | 1.789 s | 0.0352 s | -| Build_NUnit | 4.4.0 | 1.570 s | 1.571 s | 0.0178 s | -| Build_MSTest | 4.0.1 | 1.657 s | 1.661 s | 0.0240 s | -| Build_xUnit3 | 3.2.0 | 1.577 s | 1.575 s | 0.0136 s | +- [Build Performance](BuildTime) - Compilation time comparison --- @@ -70,10 +32,10 @@ These benchmarks compare TUnit against the most popular .NET testing frameworks: | Framework | Version Tested | |-----------|----------------| -| **TUnit** | 1.0.39 | +| **TUnit** | 1.0.78 | | **xUnit v3** | 3.2.0 | | **NUnit** | 4.4.0 | -| **MSTest** | 4.0.1 | +| **MSTest** | 4.0.2 | ### Test Scenarios @@ -81,15 +43,16 @@ The benchmarks measure real-world testing patterns: - **DataDrivenTests**: Parameterized tests with multiple data sources - **AsyncTests**: Realistic async/await patterns with I/O simulation -- **ScaleTests**: Large test suites (1000+ tests) measuring scalability +- **ScaleTests**: Large test suites (150+ tests) measuring scalability - **MatrixTests**: Combinatorial test generation and execution - **MassiveParallelTests**: Parallel execution stress tests +- **SetupTeardownTests**: Expensive test fixtures with setup/teardown overhead ### Environment - **OS**: Ubuntu Latest (GitHub Actions) -- **Runtime**: .NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3 -- **SDK**: .NET SDK 10.0.100-rc.2.25502.107 +- **Runtime**: .NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v3 +- **SDK**: .NET SDK 10.0.100 - **Hardware**: GitHub Actions Standard Runner (Ubuntu) - **Tool**: BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat) @@ -112,4 +75,4 @@ These benchmarks run automatically daily via [GitHub Actions](https://github.com Each benchmark runs multiple iterations with statistical analysis to ensure accuracy. Results may vary based on hardware and test characteristics. ::: -*Last generated: 2025-11-10T00:29:09.704Z* +*Last generated: 2025-11-12T00:44:12.201Z* diff --git a/docs/docs/benchmarks/results.md b/docs/docs/benchmarks/results.md new file mode 100644 index 0000000000..7fa319d416 --- /dev/null +++ b/docs/docs/benchmarks/results.md @@ -0,0 +1,63 @@ +--- +title: results +description: Performance benchmark results for results +sidebar_position: 2 +--- + +# results Benchmark + +:::info Last Updated +This benchmark was automatically generated on **2025-11-12** from the latest CI run. + +**Environment:** Ubuntu Latest • .NET SDK 10.0.100 +::: + +## šŸ“Š Results + +| Framework | Version | Mean | Median | StdDev | +|-----------|---------|------|--------|--------| +| **TUnit** | 1.0.78 | 569.0 ms | 568.5 ms | 3.62 ms | +| NUnit | 4.4.0 | 691.2 ms | 691.0 ms | 5.19 ms | +| MSTest | 4.0.2 | 658.5 ms | 655.6 ms | 5.84 ms | +| xUnit3 | 3.2.0 | 738.2 ms | 735.9 ms | 7.49 ms | +| **TUnit (AOT)** | 1.0.78 | 124.2 ms | 124.4 ms | 0.42 ms | + +## šŸ“ˆ Visual Comparison + +```mermaid +%%{init: { + 'theme':'base', + 'themeVariables': { + 'primaryColor': '#10b981', + 'primaryTextColor': '#fff', + 'primaryBorderColor': '#059669', + 'lineColor': '#d1d5db', + 'secondaryColor': '#3b82f6', + 'tertiaryColor': '#f59e0b', + 'background': '#ffffff', + 'mainBkg': '#10b981', + 'secondBkg': '#ef4444', + 'tertiaryBkg': '#f59e0b' + } +}}%% +xychart-beta + title "results Performance Comparison" + x-axis ["TUnit", "NUnit", "MSTest", "xUnit3", "TUnit_AOT"] + y-axis "Time (ms)" 0 --> 886 + bar [569, 691.2, 658.5, 738.2, 124.2] +``` + +## šŸŽÆ Key Insights + +- **1.21x faster** than NUnit (4.4.0) +- **1.16x faster** than MSTest (4.0.2) +- **1.30x faster** than xUnit3 (3.2.0) +- **4.58x faster** with Native AOT compilation + +--- + +:::note Methodology +View the [benchmarks overview](/docs/benchmarks) for methodology details and environment information. +::: + +*Last generated: 2025-11-12T00:44:12.201Z* diff --git a/docs/docs/execution/engine-modes.md b/docs/docs/execution/engine-modes.md index 4a6eefbc0b..aa45293abd 100644 --- a/docs/docs/execution/engine-modes.md +++ b/docs/docs/execution/engine-modes.md @@ -107,7 +107,7 @@ Add this MSBuild property to your test project file (`.csproj`): ```xml - net9.0 + net10.0 false diff --git a/docs/docs/test-lifecycle/property-injection.md b/docs/docs/test-lifecycle/property-injection.md index 58470f0fa9..e770ab1fc1 100644 --- a/docs/docs/test-lifecycle/property-injection.md +++ b/docs/docs/test-lifecycle/property-injection.md @@ -8,11 +8,11 @@ The required keyword keeps your code clean and correct. If a property isn't pass ## AOT-Compatible Property Attributes Supported attributes for properties in AOT mode: -- **Argument** - Compile-time constant values -- **MethodDataSource** - Static method data sources -- **ClassDataSource** - Static class-based data sources +- **MethodDataSource** - Data sources via calling a method +- **`ClassDataSource`** - A data source that injects in T - **DataSourceGeneratorAttribute** - Source-generated data (first item only) -- **ClassDataSource** - Dependency injection with service provider + +For dependency injection with service providers, inherit from `DependencyInjectionDataSourceAttribute` to create custom attributes. See [Dependency Injection](./dependency-injection.md) documentation for details. The AOT system generates strongly-typed property setters at compile time, eliminating reflection overhead and ensuring Native AOT compatibility. @@ -55,10 +55,6 @@ namespace MyTestProject; public class PropertySetterTests { - // Compile-time constant injection - [Arguments("1")] - public required string Property1 { get; init; } - // Static method data source injection [MethodDataSource(nameof(GetMethodData))] public required string Property2 { get; init; } @@ -83,7 +79,7 @@ public class PropertySetterTests [DataSourceGeneratorTests.AutoFixtureGenerator] public required string Property7 { get; init; } - // Service provider dependency injection + // Async initialization example (IAsyncInitializer) [ClassDataSource] public required AsyncPropertyExample AsyncService { get; init; } @@ -91,7 +87,6 @@ public class PropertySetterTests public async Task Test() { // All properties are automatically initialized before this test runs - await Assert.That(Property1).IsEqualTo("1"); await Assert.That(Property2).IsNotNull(); await Assert.That(Property3).IsNotNull(); await Assert.That(AsyncService.IsInitialized).IsTrue(); diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 0b75b8f24b..d9b66cd3c6 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -55,6 +55,11 @@ const config: Config = { ], ], + markdown: { + mermaid: true, + }, + themes: ['@docusaurus/theme-mermaid'], + themeConfig: { // Replace with your project's social card algolia: { diff --git a/docs/package.json b/docs/package.json index 15e14f9e45..4aab3e1654 100644 --- a/docs/package.json +++ b/docs/package.json @@ -17,6 +17,7 @@ "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/theme-mermaid": "^3.9.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.1.1", "prism-react-renderer": "^2.4.0", diff --git a/docs/sidebars.ts b/docs/sidebars.ts index fd63fab784..b53b165699 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -291,7 +291,10 @@ const sidebars: SidebarsConfig = { collapsed: false, items: [ 'benchmarks/index', - 'benchmarks/methodology', + { + type: 'autogenerated', + dirName: 'benchmarks', + }, ], }, ], diff --git a/docs/src/css/benchmark-charts.css b/docs/src/css/benchmark-charts.css new file mode 100644 index 0000000000..cf992fae08 --- /dev/null +++ b/docs/src/css/benchmark-charts.css @@ -0,0 +1,69 @@ +/* Enhanced styling for Mermaid benchmark charts */ + +/* Override Mermaid xychart bar colors for better visibility */ +.markdown article .mermaid .xychart .plot > g > g > rect:nth-child(1) { + fill: #10b981 !important; /* TUnit - Emerald Green */ + opacity: 0.9; +} + +.markdown article .mermaid .xychart .plot > g > g > rect:nth-child(2) { + fill: #ef4444 !important; /* NUnit - Red */ + opacity: 0.85; +} + +.markdown article .mermaid .xychart .plot > g > g > rect:nth-child(3) { + fill: #f59e0b !important; /* MSTest - Amber */ + opacity: 0.85; +} + +.markdown article .mermaid .xychart .plot > g > g > rect:nth-child(4) { + fill: #8b5cf6 !important; /* xUnit - Purple */ + opacity: 0.85; +} + +.markdown article .mermaid .xychart .plot > g > g > rect:nth-child(5) { + fill: #06b6d4 !important; /* TUnit AOT - Cyan */ + opacity: 0.9; +} + +/* Enhance chart readability */ +.markdown article .mermaid .xychart text { + fill: var(--ifm-font-color-base) !important; + font-family: var(--ifm-font-family-base); +} + +.markdown article .mermaid .xychart .title { + font-size: 16px; + font-weight: 600; +} + +/* Grid lines for better readability */ +.markdown article .mermaid .xychart line { + stroke: var(--ifm-color-emphasis-300); + stroke-opacity: 0.5; +} + +/* Axis styling */ +.markdown article .mermaid .xychart .xAxis line, +.markdown article .mermaid .xychart .yAxis line { + stroke: var(--ifm-color-emphasis-500); +} + +/* Dark mode adjustments */ +[data-theme='dark'] .markdown article .mermaid .xychart text { + fill: var(--ifm-font-color-base) !important; +} + +[data-theme='dark'] .markdown article .mermaid .xychart line { + stroke: var(--ifm-color-emphasis-500); +} + +/* Add subtle hover effects */ +.markdown article .mermaid .xychart .plot > g > g > rect { + transition: opacity 0.2s ease; +} + +.markdown article .mermaid .xychart .plot > g > g > rect:hover { + opacity: 1 !important; + filter: brightness(1.1); +} diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 7d4220ef57..912280f65d 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -4,6 +4,9 @@ * work well for content-centric websites. */ +/* Import benchmark chart styling */ +@import url('./benchmark-charts.css'); + /* You can override the default Infima variables here. */ :root { --ifm-color-primary: #14b8a6; diff --git a/docs/static/benchmarks/BuildTime.json b/docs/static/benchmarks/BuildTime.json new file mode 100644 index 0000000000..2f4f507e3d --- /dev/null +++ b/docs/static/benchmarks/BuildTime.json @@ -0,0 +1,43 @@ +{ + "timestamp": "2025-11-12T00:44:12.201Z", + "category": "BuildTime", + "environment": { + "benchmarkDotNetVersion": "BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)", + "sdk": ".NET SDK 10.0.100", + "host": ".NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v3" + }, + "results": [ + { + "Method": "Build_TUnit", + "Version": "1.0.78", + "Mean": "2.061 s", + "Error": "0.0216 s", + "StdDev": "0.0202 s", + "Median": "2.060 s" + }, + { + "Method": "Build_NUnit", + "Version": "4.4.0", + "Mean": "1.645 s", + "Error": "0.0165 s", + "StdDev": "0.0147 s", + "Median": "1.645 s" + }, + { + "Method": "Build_MSTest", + "Version": "4.0.2", + "Mean": "1.712 s", + "Error": "0.0149 s", + "StdDev": "0.0132 s", + "Median": "1.710 s" + }, + { + "Method": "Build_xUnit3", + "Version": "3.2.0", + "Mean": "1.615 s", + "Error": "0.0160 s", + "StdDev": "0.0149 s", + "Median": "1.619 s" + } + ] +} \ No newline at end of file diff --git a/docs/static/benchmarks/historical.json b/docs/static/benchmarks/historical.json index 9912b13410..f0a01a895b 100644 --- a/docs/static/benchmarks/historical.json +++ b/docs/static/benchmarks/historical.json @@ -1,42 +1,22 @@ [ { - "date": "2025-11-07", - "averageSpeedups": { - "vsXUnit": "1.3", - "vsNUnit": "1.2", - "vsMSTest": "1.3", - "count": 1 - }, + "date": "2025-11-11", "environment": "Ubuntu" }, { - "date": "2025-11-08", - "averageSpeedups": { - "vsXUnit": "1.2", - "vsNUnit": "1.1", - "vsMSTest": "1.0", - "count": 1 - }, + "date": "2025-11-11", "environment": "Ubuntu" }, { - "date": "2025-11-09", - "averageSpeedups": { - "vsXUnit": "0.0", - "vsNUnit": "0.0", - "vsMSTest": "0.0", - "count": 1 - }, + "date": "2025-11-12", "environment": "Ubuntu" }, { - "date": "2025-11-10", - "averageSpeedups": { - "vsXUnit": "1.2", - "vsNUnit": "1.2", - "vsMSTest": "1.0", - "count": 1 - }, + "date": "2025-11-12", + "environment": "Ubuntu" + }, + { + "date": "2025-11-12", "environment": "Ubuntu" } ] \ No newline at end of file diff --git a/docs/static/benchmarks/latest.json b/docs/static/benchmarks/latest.json index 145489d3e1..0599437f16 100644 --- a/docs/static/benchmarks/latest.json +++ b/docs/static/benchmarks/latest.json @@ -1,51 +1,51 @@ { - "timestamp": "2025-11-10T00:29:09.704Z", + "timestamp": "2025-11-12T00:44:12.201Z", "environment": { "benchmarkDotNetVersion": "BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)", - "sdk": ".NET SDK 10.0.100-rc.2.25502.107", - "host": ".NET 10.0.0 (10.0.0-rc.2.25502.107, 10.0.25.50307), X64 RyuJIT x86-64-v3" + "sdk": ".NET SDK 10.0.100", + "host": ".NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v3" }, "categories": { "results": [ { "Method": "TUnit", - "Version": "1.0.39", - "Mean": "495.43 ms", - "Error": "2.303 ms", - "StdDev": "2.042 ms", - "Median": "495.43 ms" + "Version": "1.0.78", + "Mean": "569.0 ms", + "Error": "3.87 ms", + "StdDev": "3.62 ms", + "Median": "568.5 ms" }, { "Method": "NUnit", "Version": "4.4.0", - "Mean": "578.77 ms", - "Error": "9.242 ms", - "StdDev": "7.718 ms", - "Median": "580.83 ms" + "Mean": "691.2 ms", + "Error": "5.85 ms", + "StdDev": "5.19 ms", + "Median": "691.0 ms" }, { "Method": "MSTest", - "Version": "4.0.1", - "Mean": "495.62 ms", - "Error": "7.338 ms", - "StdDev": "6.128 ms", - "Median": "496.03 ms" + "Version": "4.0.2", + "Mean": "658.5 ms", + "Error": "6.59 ms", + "StdDev": "5.84 ms", + "Median": "655.6 ms" }, { "Method": "xUnit3", "Version": "3.2.0", - "Mean": "591.61 ms", - "Error": "10.673 ms", - "StdDev": "9.984 ms", - "Median": "591.28 ms" + "Mean": "738.2 ms", + "Error": "8.45 ms", + "StdDev": "7.49 ms", + "Median": "735.9 ms" }, { "Method": "TUnit_AOT", - "Version": "1.0.39", - "Mean": "44.15 ms", - "Error": "1.112 ms", - "StdDev": "3.244 ms", - "Median": "44.00 ms" + "Version": "1.0.78", + "Mean": "124.2 ms", + "Error": "0.45 ms", + "StdDev": "0.42 ms", + "Median": "124.4 ms" } ] }, @@ -53,58 +53,42 @@ "BuildTime": [ { "Method": "Build_TUnit", - "Version": "1.0.39", - "Mean": "1.788 s", - "Error": "0.0343 s", - "StdDev": "0.0352 s", - "Median": "1.789 s" + "Version": "1.0.78", + "Mean": "2.061 s", + "Error": "0.0216 s", + "StdDev": "0.0202 s", + "Median": "2.060 s" }, { "Method": "Build_NUnit", "Version": "4.4.0", - "Mean": "1.570 s", - "Error": "0.0201 s", - "StdDev": "0.0178 s", - "Median": "1.571 s" + "Mean": "1.645 s", + "Error": "0.0165 s", + "StdDev": "0.0147 s", + "Median": "1.645 s" }, { "Method": "Build_MSTest", - "Version": "4.0.1", - "Mean": "1.657 s", - "Error": "0.0256 s", - "StdDev": "0.0240 s", - "Median": "1.661 s" + "Version": "4.0.2", + "Mean": "1.712 s", + "Error": "0.0149 s", + "StdDev": "0.0132 s", + "Median": "1.710 s" }, { "Method": "Build_xUnit3", "Version": "3.2.0", - "Mean": "1.577 s", - "Error": "0.0154 s", - "StdDev": "0.0136 s", - "Median": "1.575 s" + "Mean": "1.615 s", + "Error": "0.0160 s", + "StdDev": "0.0149 s", + "Median": "1.619 s" } ] }, - "comparisons": { - "results": { - "tunitMean": 495.43, - "tunitAOTMean": 44.15, - "vsXUnit": "1.19", - "vsNUnit": "1.17", - "vsMSTest": "1.00", - "aotSpeedup": "11.22" - } - }, - "averageSpeedups": { - "vsXUnit": "1.2", - "vsNUnit": "1.2", - "vsMSTest": "1.0", - "count": 1 - }, "stats": { "runtimeCategories": 1, "buildCategories": 1, "totalBenchmarks": 2, - "lastUpdated": "2025-11-10T00:29:09.702Z" + "lastUpdated": "2025-11-12T00:44:12.200Z" } } \ No newline at end of file diff --git a/docs/static/benchmarks/results.json b/docs/static/benchmarks/results.json new file mode 100644 index 0000000000..5c66be3364 --- /dev/null +++ b/docs/static/benchmarks/results.json @@ -0,0 +1,51 @@ +{ + "timestamp": "2025-11-12T00:44:12.201Z", + "category": "results", + "environment": { + "benchmarkDotNetVersion": "BenchmarkDotNet v0.15.6, Linux Ubuntu 24.04.3 LTS (Noble Numbat)", + "sdk": ".NET SDK 10.0.100", + "host": ".NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v3" + }, + "results": [ + { + "Method": "TUnit", + "Version": "1.0.78", + "Mean": "569.0 ms", + "Error": "3.87 ms", + "StdDev": "3.62 ms", + "Median": "568.5 ms" + }, + { + "Method": "NUnit", + "Version": "4.4.0", + "Mean": "691.2 ms", + "Error": "5.85 ms", + "StdDev": "5.19 ms", + "Median": "691.0 ms" + }, + { + "Method": "MSTest", + "Version": "4.0.2", + "Mean": "658.5 ms", + "Error": "6.59 ms", + "StdDev": "5.84 ms", + "Median": "655.6 ms" + }, + { + "Method": "xUnit3", + "Version": "3.2.0", + "Mean": "738.2 ms", + "Error": "8.45 ms", + "StdDev": "7.49 ms", + "Median": "735.9 ms" + }, + { + "Method": "TUnit_AOT", + "Version": "1.0.78", + "Mean": "124.2 ms", + "Error": "0.45 ms", + "StdDev": "0.42 ms", + "Median": "124.4 ms" + } + ] +} \ No newline at end of file diff --git a/docs/static/benchmarks/summary.json b/docs/static/benchmarks/summary.json new file mode 100644 index 0000000000..f3ba5050a2 --- /dev/null +++ b/docs/static/benchmarks/summary.json @@ -0,0 +1,10 @@ +{ + "runtime": [ + "results" + ], + "build": [ + "BuildTime" + ], + "timestamp": "2025-11-12", + "environment": "Ubuntu Latest • .NET SDK 10.0.100" +} \ No newline at end of file diff --git a/docs/yarn.lock b/docs/yarn.lock index e7b9f20ebd..884c7aca68 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -231,6 +231,19 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@antfu/install-pkg@^1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz" + integrity sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ== + dependencies: + package-manager-detector "^1.3.0" + tinyexec "^1.0.1" + +"@antfu/utils@^9.2.0": + version "9.3.0" + resolved "https://registry.npmjs.org/@antfu/utils/-/utils-9.3.0.tgz" + integrity sha512-9hFT4RauhcUzqOE4f1+frMKLZrgNog5b06I7VmZQV1BkvwvqrbC8EBZf3L1eEL2AKb6rNKjER0sEvJiSP1FXEA== + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2": version "7.26.2" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz" @@ -1137,6 +1150,43 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@braintree/sanitize-url@^7.1.1": + version "7.1.1" + resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz" + integrity sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw== + +"@chevrotain/cst-dts-gen@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz" + integrity sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ== + dependencies: + "@chevrotain/gast" "11.0.3" + "@chevrotain/types" "11.0.3" + lodash-es "4.17.21" + +"@chevrotain/gast@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz" + integrity sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q== + dependencies: + "@chevrotain/types" "11.0.3" + lodash-es "4.17.21" + +"@chevrotain/regexp-to-ast@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz" + integrity sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA== + +"@chevrotain/types@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz" + integrity sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ== + +"@chevrotain/utils@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz" + integrity sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" @@ -1873,6 +1923,19 @@ tslib "^2.6.0" utility-types "^3.10.0" +"@docusaurus/theme-mermaid@^3.9.2": + version "3.9.2" + resolved "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.9.2.tgz" + integrity sha512-5vhShRDq/ntLzdInsQkTdoKWSzw8d1jB17sNPYhA/KvYYFXfuVEGHLM6nrf8MFbV8TruAHDG21Fn3W4lO8GaDw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + mermaid ">=11.6.0" + tslib "^2.6.0" + "@docusaurus/theme-search-algolia@3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz" @@ -1985,6 +2048,25 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@iconify/types@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@iconify/utils@^3.0.1": + version "3.0.2" + resolved "https://registry.npmjs.org/@iconify/utils/-/utils-3.0.2.tgz" + integrity sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ== + dependencies: + "@antfu/install-pkg" "^1.1.0" + "@antfu/utils" "^9.2.0" + "@iconify/types" "^2.0.0" + debug "^4.4.1" + globals "^15.15.0" + kolorist "^1.8.0" + local-pkg "^1.1.1" + mlly "^1.7.4" + "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" @@ -2129,6 +2211,13 @@ dependencies: "@types/mdx" "^2.0.0" +"@mermaid-js/parser@^0.6.3": + version "0.6.3" + resolved "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.3.tgz" + integrity sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA== + dependencies: + langium "3.3.1" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -2382,6 +2471,216 @@ dependencies: "@types/node" "*" +"@types/d3-array@*": + version "3.2.2" + resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz" + integrity sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw== + +"@types/d3-axis@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz" + integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-brush@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz" + integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-chord@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz" + integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-contour@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz" + integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== + dependencies: + "@types/d3-array" "*" + "@types/geojson" "*" + +"@types/d3-delaunay@*": + version "6.0.4" + resolved "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz" + integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== + +"@types/d3-dispatch@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz" + integrity sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA== + +"@types/d3-drag@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" + integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-dsv@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== + +"@types/d3-ease@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-fetch@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== + dependencies: + "@types/d3-dsv" "*" + +"@types/d3-force@*": + version "3.0.10" + resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz" + integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw== + +"@types/d3-format@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz" + integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== + +"@types/d3-geo@*": + version "3.1.0" + resolved "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== + dependencies: + "@types/geojson" "*" + +"@types/d3-hierarchy@*": + version "3.1.7" + resolved "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz" + integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== + +"@types/d3-interpolate@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.1.1" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz" + integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== + +"@types/d3-polygon@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz" + integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== + +"@types/d3-quadtree@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz" + integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== + +"@types/d3-random@*": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz" + integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== + +"@types/d3-scale-chromatic@*": + version "3.1.0" + resolved "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz" + integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== + +"@types/d3-scale@*": + version "4.0.9" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz" + integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== + dependencies: + "@types/d3-time" "*" + +"@types/d3-selection@*": + version "3.0.11" + resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz" + integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== + +"@types/d3-shape@*": + version "3.1.7" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz" + integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time-format@*": + version "4.0.3" + resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz" + integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== + +"@types/d3-time@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz" + integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== + +"@types/d3-timer@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + +"@types/d3-transition@*": + version "3.0.9" + resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz" + integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-zoom@*": + version "3.0.8" + resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" + integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== + dependencies: + "@types/d3-interpolate" "*" + "@types/d3-selection" "*" + +"@types/d3@^7.4.3": + version "7.4.3" + resolved "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz" + integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== + dependencies: + "@types/d3-array" "*" + "@types/d3-axis" "*" + "@types/d3-brush" "*" + "@types/d3-chord" "*" + "@types/d3-color" "*" + "@types/d3-contour" "*" + "@types/d3-delaunay" "*" + "@types/d3-dispatch" "*" + "@types/d3-drag" "*" + "@types/d3-dsv" "*" + "@types/d3-ease" "*" + "@types/d3-fetch" "*" + "@types/d3-force" "*" + "@types/d3-format" "*" + "@types/d3-geo" "*" + "@types/d3-hierarchy" "*" + "@types/d3-interpolate" "*" + "@types/d3-path" "*" + "@types/d3-polygon" "*" + "@types/d3-quadtree" "*" + "@types/d3-random" "*" + "@types/d3-scale" "*" + "@types/d3-scale-chromatic" "*" + "@types/d3-selection" "*" + "@types/d3-shape" "*" + "@types/d3-time" "*" + "@types/d3-time-format" "*" + "@types/d3-timer" "*" + "@types/d3-transition" "*" + "@types/d3-zoom" "*" + "@types/debug@^4.0.0": version "4.1.12" resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz" @@ -2437,6 +2736,11 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/geojson@*": + version "7946.0.16" + resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz" + integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== + "@types/gtag.js@^0.0.12": version "0.0.12" resolved "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz" @@ -2632,6 +2936,11 @@ dependencies: "@types/node" "*" +"@types/trusted-types@^2.0.7": + version "2.0.7" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + "@types/unist@*", "@types/unist@^3.0.0": version "3.0.2" resolved "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz" @@ -2815,10 +3124,10 @@ acorn-walk@^8.0.0: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.0.4, acorn@^8.14.0, acorn@^8.8.2: - version "8.14.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz" - integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.0.4, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.8.2: + version "8.15.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== address@^1.0.1: version "1.2.2" @@ -3307,6 +3616,25 @@ cheerio@1.0.0-rc.12: parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" +chevrotain-allstar@~0.3.0: + version "0.3.1" + resolved "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz" + integrity sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw== + dependencies: + lodash-es "^4.17.21" + +chevrotain@^11.0.0, chevrotain@~11.0.3: + version "11.0.3" + resolved "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz" + integrity sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw== + dependencies: + "@chevrotain/cst-dts-gen" "11.0.3" + "@chevrotain/gast" "11.0.3" + "@chevrotain/regexp-to-ast" "11.0.3" + "@chevrotain/types" "11.0.3" + "@chevrotain/utils" "11.0.3" + lodash-es "4.17.21" + chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" @@ -3434,6 +3762,11 @@ commander@^8.3.0: resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@7: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + common-path-prefix@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz" @@ -3464,6 +3797,16 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== + +confbox@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz" + integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ== + config-chain@^1.1.11: version "1.1.13" resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" @@ -3559,6 +3902,20 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cose-base@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz" + integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== + dependencies: + layout-base "^1.0.0" + +cose-base@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz" + integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== + dependencies: + layout-base "^2.0.0" + cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: version "8.3.6" resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz" @@ -3764,17 +4121,320 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +cytoscape-cose-bilkent@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz" + integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== + dependencies: + cose-base "^1.0.0" + +cytoscape-fcose@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz" + integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== + dependencies: + cose-base "^2.2.0" + +cytoscape@^3.2.0, cytoscape@^3.29.3: + version "3.33.1" + resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz" + integrity sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ== + +d3-array@^3.2.0, "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3: + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +"d3-array@1 - 2": + version "2.12.1" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + +d3-axis@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" + integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== + +d3-brush@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz" + integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "3" + d3-transition "3" + +d3-chord@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz" + integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== + dependencies: + d3-path "1 - 3" + +"d3-color@1 - 3", d3-color@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-contour@4: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz" + integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== + dependencies: + d3-array "^3.2.0" + +d3-delaunay@6: + version "6.0.4" + resolved "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz" + integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== + dependencies: + delaunator "5" + +"d3-dispatch@1 - 3", d3-dispatch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +"d3-drag@2 - 3", d3-drag@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +"d3-dsv@1 - 3", d3-dsv@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz" + integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== + dependencies: + commander "7" + iconv-lite "0.6" + rw "1" + +"d3-ease@1 - 3", d3-ease@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +d3-fetch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz" + integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== + dependencies: + d3-dsv "1 - 3" + +d3-force@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" + integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== + dependencies: + d3-dispatch "1 - 3" + d3-quadtree "1 - 3" + d3-timer "1 - 3" + +"d3-format@1 - 3", d3-format@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +d3-geo@3: + version "3.1.1" + resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz" + integrity sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q== + dependencies: + d3-array "2.5.0 - 3" + +d3-hierarchy@3: + version "3.1.2" + resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" + integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== + +"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@^3.1.0, "d3-path@1 - 3", d3-path@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-path@1: + version "1.0.9" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +d3-polygon@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" + integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== + +"d3-quadtree@1 - 3", d3-quadtree@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + +d3-random@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz" + integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== + +d3-sankey@^0.12.3: + version "0.12.3" + resolved "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz" + integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== + dependencies: + d3-array "1 - 2" + d3-shape "^1.2.0" + +d3-scale-chromatic@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz" + integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== + dependencies: + d3-color "1 - 3" + d3-interpolate "1 - 3" + +d3-scale@4: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +"d3-selection@2 - 3", d3-selection@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +d3-shape@3: + version "3.2.0" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +"d3-time-format@2 - 4", d3-time-format@4: + version "4.1.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + +"d3-timer@1 - 3", d3-timer@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + +"d3-transition@2 - 3", d3-transition@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +d3-zoom@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + +d3@^7.9.0: + version "7.9.0" + resolved "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz" + integrity sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA== + dependencies: + d3-array "3" + d3-axis "3" + d3-brush "3" + d3-chord "3" + d3-color "3" + d3-contour "4" + d3-delaunay "6" + d3-dispatch "3" + d3-drag "3" + d3-dsv "3" + d3-ease "3" + d3-fetch "3" + d3-force "3" + d3-format "3" + d3-geo "3" + d3-hierarchy "3" + d3-interpolate "3" + d3-path "3" + d3-polygon "3" + d3-quadtree "3" + d3-random "3" + d3-scale "4" + d3-scale-chromatic "3" + d3-selection "3" + d3-shape "3" + d3-time "3" + d3-time-format "4" + d3-timer "3" + d3-transition "3" + d3-zoom "3" + +dagre-d3-es@7.0.13: + version "7.0.13" + resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz" + integrity sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q== + dependencies: + d3 "^7.9.0" + lodash-es "^4.17.21" + +dayjs@^1.11.18: + version "1.11.19" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz" + integrity sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw== + debounce@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.4.1, debug@4: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: - ms "2.1.2" + ms "^2.1.3" debug@2.6.9: version "2.6.9" @@ -3853,6 +4513,13 @@ define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delaunator@5: + version "5.0.1" + resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz" + integrity sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw== + dependencies: + robust-predicates "^3.0.2" + depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" @@ -3951,6 +4618,13 @@ domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" +dompurify@^3.2.5: + version "3.3.0" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz" + integrity sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ== + optionalDependencies: + "@types/trusted-types" "^2.0.7" + domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" @@ -4284,6 +4958,11 @@ express@^4.21.2: utils-merge "1.0.1" vary "~1.1.2" +exsolve@^1.0.7: + version "1.0.8" + resolved "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz" + integrity sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA== + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" @@ -4512,6 +5191,11 @@ globals@^11.1.0: resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^15.15.0: + version "15.15.0" + resolved "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz" + integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg== + globby@^11.1.0: version "11.1.0" resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" @@ -4586,6 +5270,11 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" +hachure-fill@^0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz" + integrity sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg== + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" @@ -4926,6 +5615,13 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" @@ -5004,6 +5700,16 @@ inline-style-parser@0.2.2: resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz" integrity sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ== +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + invariant@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" @@ -5336,6 +6042,13 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +katex@^0.16.22: + version "0.16.25" + resolved "https://registry.npmjs.org/katex/-/katex-0.16.25.tgz" + integrity sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q== + dependencies: + commander "^8.3.0" + keyv@^4.5.3: version "4.5.4" resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" @@ -5343,6 +6056,11 @@ keyv@^4.5.3: dependencies: json-buffer "3.0.1" +khroma@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz" + integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw== + kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" @@ -5353,6 +6071,22 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kolorist@^1.8.0: + version "1.8.0" + resolved "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== + +langium@3.3.1: + version "3.3.1" + resolved "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz" + integrity sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w== + dependencies: + chevrotain "~11.0.3" + chevrotain-allstar "~0.3.0" + vscode-languageserver "~9.0.1" + vscode-languageserver-textdocument "~1.0.11" + vscode-uri "~3.0.8" + latest-version@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz" @@ -5368,6 +6102,16 @@ launch-editor@^2.6.1: picocolors "^1.1.1" shell-quote "^1.8.3" +layout-base@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz" + integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== + +layout-base@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz" + integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== + leven@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" @@ -5397,6 +6141,15 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" +local-pkg@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz" + integrity sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A== + dependencies: + mlly "^1.7.4" + pkg-types "^2.3.0" + quansync "^0.2.11" + locate-path@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz" @@ -5404,6 +6157,11 @@ locate-path@^7.1.0: dependencies: p-locate "^6.0.0" +lodash-es@^4.17.21, lodash-es@4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" @@ -5479,7 +6237,7 @@ markdown-table@^3.0.0: resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz" integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== -marked@^16.3.0: +marked@^16.2.1, marked@^16.3.0: version "16.3.0" resolved "https://registry.npmjs.org/marked/-/marked-16.3.0.tgz" integrity sha512-K3UxuKu6l6bmA5FUwYho8CfJBlsUWAooKtdGgMcERSpF7gcBUrCGsLH7wDaaNOzwq18JzSUDyoEb/YsrqMac3w== @@ -5743,6 +6501,32 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +mermaid@>=11.6.0: + version "11.12.1" + resolved "https://registry.npmjs.org/mermaid/-/mermaid-11.12.1.tgz" + integrity sha512-UlIZrRariB11TY1RtTgUWp65tphtBv4CSq7vyS2ZZ2TgoMjs2nloq+wFqxiwcxlhHUvs7DPGgMjs2aeQxz5h9g== + dependencies: + "@braintree/sanitize-url" "^7.1.1" + "@iconify/utils" "^3.0.1" + "@mermaid-js/parser" "^0.6.3" + "@types/d3" "^7.4.3" + cytoscape "^3.29.3" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.2.0" + d3 "^7.9.0" + d3-sankey "^0.12.3" + dagre-d3-es "7.0.13" + dayjs "^1.11.18" + dompurify "^3.2.5" + katex "^0.16.22" + khroma "^2.1.0" + lodash-es "^4.17.21" + marked "^16.2.1" + roughjs "^4.6.6" + stylis "^4.3.6" + ts-dedent "^2.2.0" + uuid "^11.1.0" + methods@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" @@ -6272,26 +7056,31 @@ minimist@^1.2.0: resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +mlly@^1.7.4: + version "1.8.0" + resolved "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz" + integrity sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g== + dependencies: + acorn "^8.15.0" + pathe "^2.0.3" + pkg-types "^1.3.1" + ufo "^1.6.1" + mrmime@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz" integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== +ms@^2.1.3, ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - multicast-dns@^7.2.5: version "7.2.5" resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" @@ -6523,6 +7312,11 @@ package-json@^8.1.0: registry-url "^6.0.0" semver "^7.3.7" +package-manager-detector@^1.3.0: + version "1.5.0" + resolved "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.5.0.tgz" + integrity sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz" @@ -6595,6 +7389,11 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" +path-data-parser@^0.1.0, path-data-parser@0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz" + integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== + path-exists@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz" @@ -6637,6 +7436,11 @@ path-type@^4.0.0: resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathe@^2.0.1, pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + periscopic@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz" @@ -6663,6 +7467,37 @@ pkg-dir@^7.0.0: dependencies: find-up "^6.3.0" +pkg-types@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz" + integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ== + dependencies: + confbox "^0.1.8" + mlly "^1.7.4" + pathe "^2.0.1" + +pkg-types@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz" + integrity sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig== + dependencies: + confbox "^0.2.2" + exsolve "^1.0.7" + pathe "^2.0.3" + +points-on-curve@^0.2.0, points-on-curve@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz" + integrity sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A== + +points-on-path@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz" + integrity sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g== + dependencies: + path-data-parser "0.1.0" + points-on-curve "0.2.0" + postcss-attribute-case-insensitive@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz" @@ -7305,6 +8140,11 @@ qs@6.13.0: dependencies: side-channel "^1.0.6" +quansync@^0.2.11: + version "0.2.11" + resolved "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz" + integrity sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" @@ -7702,6 +8542,21 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +robust-predicates@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" + integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== + +roughjs@^4.6.6: + version "4.6.6" + resolved "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz" + integrity sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ== + dependencies: + hachure-fill "^0.5.2" + path-data-parser "^0.1.0" + points-on-curve "^0.2.0" + points-on-path "^0.2.1" + rtlcss@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz" @@ -7724,6 +8579,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rw@1: + version "1.3.3" + resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" + integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== + safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -7739,7 +8599,7 @@ safe-buffer@5.1.2: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -8227,6 +9087,11 @@ stylehacks@^6.1.1: browserslist "^4.23.0" postcss-selector-parser "^6.0.16" +stylis@^4.3.6: + version "4.3.6" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz" + integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" @@ -8323,6 +9188,11 @@ tiny-warning@^1.0.0: resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tinyexec@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz" + integrity sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg== + tinypool@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz" @@ -8360,6 +9230,11 @@ trough@^2.0.0: resolved "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== +ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.0, tslib@2: version "2.6.2" resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" @@ -8400,6 +9275,11 @@ typescript@>=4.9.5, typescript@~5.9.0: resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== +ufo@^1.6.1: + version "1.6.1" + resolved "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz" + integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== + undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" @@ -8585,6 +9465,11 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" @@ -8625,6 +9510,41 @@ vfile@^6.0.0, vfile@^6.0.1: unist-util-stringify-position "^4.0.0" vfile-message "^4.0.0" +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== + +vscode-languageserver-protocol@3.17.5: + version "3.17.5" + resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== + dependencies: + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" + +vscode-languageserver-textdocument@~1.0.11: + version "1.0.12" + resolved "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz" + integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA== + +vscode-languageserver-types@3.17.5: + version "3.17.5" + resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== + +vscode-languageserver@~9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz" + integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g== + dependencies: + vscode-languageserver-protocol "3.17.5" + +vscode-uri@~3.0.8: + version "3.0.8" + resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== + watchpack@^2.4.1: version "2.4.2" resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz" diff --git a/tools/speed-comparison/UnifiedTests/SetupTeardownTests.cs b/tools/speed-comparison/UnifiedTests/SetupTeardownTests.cs new file mode 100644 index 0000000000..613d9a842a --- /dev/null +++ b/tools/speed-comparison/UnifiedTests/SetupTeardownTests.cs @@ -0,0 +1,380 @@ +using System.Text; +using System.Threading.Tasks; + +namespace UnifiedTests; + +[TestClass] +#if XUNIT3 +public class SetupTeardownTests : IDisposable +#else +public class SetupTeardownTests +#endif +{ + // Simulated expensive state + private byte[] _databaseConnection; + private List _tempFiles; + private HttpClient _httpClient; + private StringBuilder _logBuilder; + +#if TUNIT + [Before(Test)] + public async Task Setup() +#elif XUNIT3 + public SetupTeardownTests() +#elif NUNIT + [SetUp] + public async Task Setup() +#elif MSTEST + [TestInitialize] + public async Task Setup() +#else + public async Task Setup() +#endif + { +#if XUNIT3 + SetupCore().GetAwaiter().GetResult(); + } + + private async Task SetupCore() + { +#endif + // Simulate expensive database connection initialization + _databaseConnection = new byte[1024 * 100]; // 100KB allocation + for (int i = 0; i < _databaseConnection.Length; i++) + { + _databaseConnection[i] = (byte)(i % 256); + } + + // Simulate file system setup + _tempFiles = []; + await Task.Delay(5); // Simulate async I/O + + // Simulate HTTP client initialization + _httpClient = new HttpClient + { + Timeout = TimeSpan.FromSeconds(30) + }; + + // Simulate logging infrastructure + _logBuilder = new StringBuilder(1000); + _logBuilder.AppendLine($"Test started at {DateTime.UtcNow}"); + + // Simulate loading configuration + await Task.Delay(5); + } + +#if TUNIT + [After(Test)] + public async Task Cleanup() +#elif XUNIT3 + public void Dispose() +#elif NUNIT + [TearDown] + public async Task Cleanup() +#elif MSTEST + [TestCleanup] + public async Task Cleanup() +#else + public async Task Cleanup() +#endif + { +#if XUNIT3 + CleanupCore().GetAwaiter().GetResult(); + } + + private async Task CleanupCore() + { +#endif + // Simulate database connection cleanup + if (_databaseConnection != null) + { + Array.Clear(_databaseConnection, 0, _databaseConnection.Length); + _databaseConnection = null!; + } + + // Simulate file cleanup + if (_tempFiles != null) + { + await Task.Delay(5); // Simulate async I/O + _tempFiles.Clear(); + _tempFiles = null!; + } + + // Cleanup HTTP client + _httpClient?.Dispose(); + _httpClient = null!; + + // Finalize logging + if (_logBuilder != null) + { + _logBuilder.AppendLine($"Test completed at {DateTime.UtcNow}"); + _logBuilder.Clear(); + _logBuilder = null!; + } + + await Task.Delay(5); // Simulate async cleanup + } + + [Test] + public void DatabaseOperationTest() + { + // Simulate database query + var sum = 0; + for (int i = 0; i < 1000; i++) + { + sum += _databaseConnection[i]; + } + _logBuilder.AppendLine($"Database operation result: {sum}"); + } + + [Test] + public async Task AsyncDatabaseOperationTest() + { + // Simulate async database operation + await Task.Delay(10); + var sum = 0; + for (int i = 0; i < 1000; i++) + { + sum += _databaseConnection[i]; + } + _logBuilder.AppendLine($"Async database operation result: {sum}"); + } + + [Test] + public void FileSystemOperationTest() + { + // Simulate file operations + for (int i = 0; i < 10; i++) + { + _tempFiles.Add($"temp_file_{i}.txt"); + } + _logBuilder.AppendLine($"Created {_tempFiles.Count} temp files"); + } + + [Test] + public async Task AsyncFileSystemOperationTest() + { + // Simulate async file operations + await Task.Delay(10); + for (int i = 0; i < 10; i++) + { + _tempFiles.Add($"async_temp_file_{i}.txt"); + } + _logBuilder.AppendLine($"Created {_tempFiles.Count} temp files asynchronously"); + } + + [Test] + public void HttpClientOperationTest() + { + // Simulate HTTP client usage + var timeout = _httpClient.Timeout; + _logBuilder.AppendLine($"HTTP client timeout: {timeout.TotalSeconds}s"); + } + + [Test] + public async Task AsyncHttpClientOperationTest() + { + // Simulate async HTTP operation + await Task.Delay(10); + var timeout = _httpClient.Timeout; + _logBuilder.AppendLine($"Async HTTP client timeout: {timeout.TotalSeconds}s"); + } + + [Test] + public void LoggingOperationTest() + { + // Simulate logging + for (int i = 0; i < 50; i++) + { + _logBuilder.AppendLine($"Log entry {i}"); + } + } + + [Test] + public async Task AsyncLoggingOperationTest() + { + // Simulate async logging + await Task.Delay(10); + for (int i = 0; i < 50; i++) + { + _logBuilder.AppendLine($"Async log entry {i}"); + } + } + + [Test] + public void MemoryIntensiveOperationTest() + { + // Simulate memory-intensive operation + var tempBuffer = new byte[1024 * 50]; // 50KB + for (int i = 0; i < tempBuffer.Length; i++) + { + tempBuffer[i] = _databaseConnection[i % _databaseConnection.Length]; + } + var sum = tempBuffer.Sum(b => (int)b); + _logBuilder.AppendLine($"Memory operation result: {sum}"); + } + + [Test] + public async Task AsyncMemoryIntensiveOperationTest() + { + // Simulate async memory-intensive operation + await Task.Delay(10); + var tempBuffer = new byte[1024 * 50]; // 50KB + for (int i = 0; i < tempBuffer.Length; i++) + { + tempBuffer[i] = _databaseConnection[i % _databaseConnection.Length]; + } + var sum = tempBuffer.Sum(b => (int)b); + _logBuilder.AppendLine($"Async memory operation result: {sum}"); + } + + [Test] + public void ComputationTest() + { + // Simulate computation + var result = 0; + for (int i = 0; i < 10000; i++) + { + result += i * i; + } + _logBuilder.AppendLine($"Computation result: {result}"); + } + + [Test] + public async Task AsyncComputationTest() + { + // Simulate async computation + await Task.Delay(10); + var result = 0; + for (int i = 0; i < 10000; i++) + { + result += i * i; + } + _logBuilder.AppendLine($"Async computation result: {result}"); + } + + [Test] + public void StringManipulationTest() + { + // Simulate string operations + var sb = new StringBuilder(); + for (int i = 0; i < 100; i++) + { + sb.Append($"Item {i}, "); + } + _logBuilder.AppendLine($"String length: {sb.Length}"); + } + + [Test] + public async Task AsyncStringManipulationTest() + { + // Simulate async string operations + await Task.Delay(10); + var sb = new StringBuilder(); + for (int i = 0; i < 100; i++) + { + sb.Append($"Item {i}, "); + } + _logBuilder.AppendLine($"Async string length: {sb.Length}"); + } + + [Test] + public void CollectionOperationTest() + { + // Simulate collection operations + var numbers = Enumerable.Range(0, 1000).ToList(); + var filtered = numbers.Where(n => n % 2 == 0).ToList(); + _logBuilder.AppendLine($"Filtered count: {filtered.Count}"); + } + + [Test] + public async Task AsyncCollectionOperationTest() + { + // Simulate async collection operations + await Task.Delay(10); + var numbers = Enumerable.Range(0, 1000).ToList(); + var filtered = numbers.Where(n => n % 2 == 0).ToList(); + _logBuilder.AppendLine($"Async filtered count: {filtered.Count}"); + } + + [Test] + public void DateTimeOperationTest() + { + // Simulate datetime operations + var start = DateTime.UtcNow; + var timestamps = new List(); + for (int i = 0; i < 100; i++) + { + timestamps.Add(start.AddSeconds(i)); + } + _logBuilder.AppendLine($"Timestamps created: {timestamps.Count}"); + } + + [Test] + public async Task AsyncDateTimeOperationTest() + { + // Simulate async datetime operations + await Task.Delay(10); + var start = DateTime.UtcNow; + var timestamps = new List(); + for (int i = 0; i < 100; i++) + { + timestamps.Add(start.AddSeconds(i)); + } + _logBuilder.AppendLine($"Async timestamps created: {timestamps.Count}"); + } + + [Test] + public void DictionaryOperationTest() + { + // Simulate dictionary operations + var dict = new Dictionary(); + for (int i = 0; i < 100; i++) + { + dict[$"key_{i}"] = i * 2; + } + _logBuilder.AppendLine($"Dictionary size: {dict.Count}"); + } + + [Test] + public async Task AsyncDictionaryOperationTest() + { + // Simulate async dictionary operations + await Task.Delay(10); + var dict = new Dictionary(); + for (int i = 0; i < 100; i++) + { + dict[$"key_{i}"] = i * 2; + } + _logBuilder.AppendLine($"Async dictionary size: {dict.Count}"); + } + + [Test] + public void JsonOperationTest() + { + // Simulate JSON serialization + var data = new + { + Id = 123, + Name = "Test Data", + Values = Enumerable.Range(0, 50).ToArray() + }; + var json = System.Text.Json.JsonSerializer.Serialize(data); + _logBuilder.AppendLine($"JSON length: {json.Length}"); + } + + [Test] + public async Task AsyncJsonOperationTest() + { + // Simulate async JSON operations + await Task.Delay(10); + var data = new + { + Id = 123, + Name = "Test Data", + Values = Enumerable.Range(0, 50).ToArray() + }; + var json = System.Text.Json.JsonSerializer.Serialize(data); + _logBuilder.AppendLine($"Async JSON length: {json.Length}"); + } +}