From 9c113767ecbbdca0cb64927e7c023b8c8258e1a2 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 26 Dec 2025 12:05:07 -0800 Subject: [PATCH] feat(tests): update tests to use GBM for random data generation; improve consistency and realism in Skew and Variance tests; refine validation logic in Beta tests --- .clinerules/MODELS.md | 6 ++++ .github/workflows/Publish.yml | 31 ++++++++++++-------- lib/statistics/beta/Beta.Validation.Tests.cs | 2 +- lib/statistics/skew/Skew.Tests.cs | 4 +-- lib/statistics/variance/Variance.Tests.cs | 4 +-- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/.clinerules/MODELS.md b/.clinerules/MODELS.md index ab3a17f4..3ca4fb01 100644 --- a/.clinerules/MODELS.md +++ b/.clinerules/MODELS.md @@ -11,6 +11,12 @@ These tests verify the internal logic, state management, and API contract of the - **`Constructor_ValidatesInput`**: Verify that invalid parameters (e.g., `period <= 0`) throw `ArgumentException`. - **`Constructor_ValidatesOptionalArgs`**: If applicable, verify other parameters (e.g., `alpha`, `sigma`). +### Random Data Generation + +- **Use `GBM` Helper**: Always use the `GBM` (Geometric Brownian Motion) helper class for generating random test data. +- **Avoid `System.Random`**: Do not use `System.Random` directly in tests to ensure consistency and realism. +- **Example**: `var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 123);` + ### Basic Functionality - **`Calc_ReturnsValue`**: Verify `Update` returns a valid `TValue` and updates the `Last` property. diff --git a/.github/workflows/Publish.yml b/.github/workflows/Publish.yml index 454f2b85..6529c19d 100644 --- a/.github/workflows/Publish.yml +++ b/.github/workflows/Publish.yml @@ -19,12 +19,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: - contents: write - pull-requests: read - security-events: write - checks: write - actions: read +permissions: {} env: DOTNET_VERSION: '10.x' @@ -37,6 +32,8 @@ jobs: # ============================================================================== Build_Test_Coverage: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout repository uses: actions/checkout@v4 @@ -94,6 +91,8 @@ jobs: Sonar_Analysis: needs: Build_Test_Coverage runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout repository uses: actions/checkout@v4 @@ -167,6 +166,11 @@ jobs: Qodana_Scan: needs: Build_Test_Coverage runs-on: ubuntu-latest + permissions: + contents: read + checks: write + security-events: write + pull-requests: read steps: - uses: actions/checkout@v4 with: @@ -191,6 +195,8 @@ jobs: Codacy_Upload: needs: Build_Test_Coverage runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v4 with: @@ -230,6 +236,8 @@ jobs: # ============================================================================== Snyk_Scan: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v4 with: @@ -292,13 +300,12 @@ jobs: # ============================================================================== Publish_Package: needs: [Build_Test_Coverage, Sonar_Analysis, Qodana_Scan, Codacy_Upload, Snyk_Scan, CodeQL_Analysis] - if: | - success() && - ( - (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' || endsWith(github.ref, '-dev'))) || - github.event_name == 'workflow_dispatch' - ) + if: >- + (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' || endsWith(github.ref, '-dev'))) || + github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v4 with: diff --git a/lib/statistics/beta/Beta.Validation.Tests.cs b/lib/statistics/beta/Beta.Validation.Tests.cs index 9d4823ed..40bb3064 100644 --- a/lib/statistics/beta/Beta.Validation.Tests.cs +++ b/lib/statistics/beta/Beta.Validation.Tests.cs @@ -93,7 +93,7 @@ public class BetaValidationTests : IDisposable double ql = qlBeta[i]; // Skender might return null/0 for warmup. - if (sk != 0) + if (Math.Abs(sk) > 1e-10) { Assert.Equal(sk, ql, ValidationHelper.DefaultTolerance); } diff --git a/lib/statistics/skew/Skew.Tests.cs b/lib/statistics/skew/Skew.Tests.cs index 235f9f36..83aed794 100644 --- a/lib/statistics/skew/Skew.Tests.cs +++ b/lib/statistics/skew/Skew.Tests.cs @@ -176,11 +176,11 @@ public class SkewTests { // Run for > 1000 updates to trigger Resync var skew = new Skew(10); - var random = new Random(123); + var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 123); for (int i = 0; i < 1100; i++) { - skew.Update(new TValue(DateTime.UtcNow, random.NextDouble() * 100)); + skew.Update(new TValue(DateTime.UtcNow, gbm.Next().Close)); } Assert.True(double.IsFinite(skew.Last.Value)); diff --git a/lib/statistics/variance/Variance.Tests.cs b/lib/statistics/variance/Variance.Tests.cs index d2695a07..a1d5f655 100644 --- a/lib/statistics/variance/Variance.Tests.cs +++ b/lib/statistics/variance/Variance.Tests.cs @@ -154,11 +154,11 @@ public class VarianceTests { // Run for > 1000 updates to trigger Resync var variance = new Variance(10); - var random = new Random(123); + var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 123); for (int i = 0; i < 1100; i++) { - variance.Update(new TValue(DateTime.UtcNow, random.NextDouble() * 100)); + variance.Update(new TValue(DateTime.UtcNow, gbm.Next().Close)); } Assert.True(double.IsFinite(variance.Last.Value));