UnitAutogen.psd1
|
@{ ModuleVersion = '0.16.1' GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' Author = 'Munaf Ibrahim Khatri' CompanyName = 'UnitAutogen' Copyright = '(C) 2026 Munaf Ibrahim Khatri. Licensed under AGPL-3.0.' Description = 'PowerShell module for UnitAutogen - auto-generated tSQLt unit tests with real branch coverage for SQL Server. Installs the framework AND the in-database (SQLCLR) predicate parser, runs generation and coverage, and exports Cobertura XML, JUnit XML, and HTML reports for Azure DevOps, GitHub Actions, Jenkins, GitLab CI, and SonarQube. The single C# predicate parser runs inside SQL Server (no PowerShell-side parser); installation registers it and requires sysadmin once plus ''clr enabled''=1.' PowerShellVersion = '5.1' RootModule = 'UnitAutogen.psm1' FunctionsToExport = @( 'Install-UnitAutogenDatabase', 'Invoke-UnitAutogen', 'Export-CoverageCoberturaXml', 'Export-TestResultsJunitXml', 'Export-CoverageHtmlReport', 'Export-UnitAutogenTests' ) CmdletsToExport = @() VariablesToExport = @() AliasesToExport = @() # All files that must be present for the module to work FileList = @( 'UnitAutogen.psd1', 'UnitAutogen.psm1', 'sql\Install_UnitAutogen.sql', 'sql\Install-UnitAutogenClr.SSMS.sql' ) PrivateData = @{ PSData = @{ ExternalModuleDependencies = @('SqlServer') Tags = @('SQL', 'SQLServer', 'tSQLt', 'Coverage', 'CI-CD', 'Cobertura', 'JUnit', 'AzureDevOps', 'Testing', 'UnitTest', 'CodeCoverage', 'BranchCoverage', 'DatabaseTesting', 'AutomatedTesting') LicenseUri = 'https://github.com/unitautogen/unitautogen-public-repo/blob/main/LICENSE' ProjectUri = 'https://github.com/unitautogen/unitautogen-public-repo' IconUri = 'https://raw.githubusercontent.com/unitautogen/unitautogen-public-repo/main/docs/logo.png' ReleaseNotes = @' ## v0.16.1 (beta) - 2026-06-15 Two narrower derived-value and aggregate shapes are now seeded to full branch coverage. - A derived local that uses SUBTRACTION (e.g. value = qty * price - fee, or qty * price - 100) is now covered. A subtracted column is neutralised to 0 like any other term; a subtracted (or added) numeric constant is folded into the knob so the driving term still crosses the threshold exactly. - An aggregate gate whose source has a NON-equality filter is now satisfied: numeric >, >=, <, <= seed a value just inside the bound; IN (...) seeds the first list value; BETWEEN seeds the low bound. (Equality and date ">=" windows were already handled.) - Validated on a synthetic loop procedure (100% line + branch); full regression on AdventureWorks2025 (PredicateZoo aggregate/scalar gates), a JSON/MERGE/transaction procedure, and a multi-procedure analytics DB all unchanged. No C#/CLR change. ## v0.16.0 (beta) - 2026-06-15 Two more derived-value and aggregate shapes are now seeded to full branch coverage. - A derived local that MIXES multiplication and addition (e.g. value = qty * price + fee) is now covered. The generator splits the expression into additive terms, drives the term holding the chosen column and neutralises the rest, so the computed value crosses the threshold exactly. Pure-product and pure-sum cases are unchanged. - An aggregate gate whose source has a NON-date filter (e.g. AVG(Score) FROM Metrics WHERE Status='ACTIVE') now seeds a row that PASSES the filter instead of a placeholder the filter excluded (which left the aggregate NULL and the branch uncovered). This also fixes compound gates that reuse such an aggregate to set a flag. - Validated on a synthetic loop procedure (100% line + branch); full regression on AdventureWorks2025 (PredicateZoo aggregate/scalar gates), a JSON/MERGE/transaction procedure, and a multi-procedure analytics DB all unchanged. No C#/CLR change. ## v0.15.9 (beta) - 2026-06-15 A correctness fix to derived-arithmetic seeding, plus several seeding bug fixes. - FIX: a witness for a derived-arithmetic branch could PASS without actually COVERING its arm when the value was derived through an aggregate over another table - the test's baseline seed row for that table shifted the aggregate, so the computed value missed the threshold. The generator now clears such aggregate-source tables after the baseline seeding, so the witness's own seed controls the aggregate. On a trade- reconciliation procedure this lifted branch coverage from 62.5% to 93.8%. - More gate shapes are now seeded: an aggregate-band gate over a date-windowed table (a previous illegal EXEC-argument expression is fixed), an operand assigned from a loop #temp, and an OR of column comparisons. - Validated; full regression on AdventureWorks2025 (PredicateZoo), a JSON/MERGE/ transaction procedure, and a multi-procedure analytics DB all unchanged. No C#/CLR change. ## v0.15.8 (beta) - 2026-06-15 Reverse seeding for derived arithmetic locals now also handles compound conditions and sum / multi-step expressions. - A compound branch like "IF @AdjustedValue > 100000 AND @WavePatternPhase = 'C'", where the second test depends on a different source (a flag set from an aggregate over another table), is now seeded by coordinating BOTH sources: the arithmetic driver as before, plus a synthesised seed for the aggregate that sets the flag (one row past the threshold, with any date-window filter satisfied). A compound gate whose extra condition cannot be satisfied still stays honestly NOT_TESTABLE. - Derived locals built with addition (a + b) are now handled alongside products, and the driver is traced through intermediate locals (a = b; b = c * Col) - multi-hop - to its source column. - Validated: a trade-reconciliation proc's compound risk-limit branch went from skipped to covered, and a synthetic loop proc's sum and multi-hop branches reached 100%. Full regression on AdventureWorks2025 (PredicateZoo), a JSON/MERGE/transaction proc, and a multi-procedure analytics DB all unchanged. No C#/CLR change. ## v0.15.7 (beta) - 2026-06-15 Reverse seeding now covers a branch whose condition compares a DERIVED arithmetic local to a literal - e.g. "IF @AdjustedValue > 50000" where @AdjustedValue = @Volume * @Price * @RiskMultiplier is computed from per-row loop columns and other locals. - Such a gate was previously skipped NOT_TESTABLE ("comparison does not involve an aggregate/scalar subquery"). The seeder now traces the operand through its arithmetic to the source columns, neutralises the co-factor columns (so the product reduces to a single driving column), pins non-row factors via the existing FakeTable of every referenced table, and sets the driving column deterministically just past the literal - covering the arm without a search (which also avoids the per-gate sweep timeout on loop procedures). - Restricted to a simple single comparison; a compound gate (e.g. "@v > 100000 AND @phase = 'C'") with a conjunct the path cannot satisfy stays honestly NOT_TESTABLE. - Validated on a trade-reconciliation loop procedure (two derived-local arms skip -> covered, with verified seeds + an OUTPUT assertion); full regression on AdventureWorks2025 (PredicateZoo), a JSON/MERGE/transaction procedure, and a multi-procedure analytics database all unchanged. No C#/CLR change. ## v0.15.6 (beta) - 2026-06-15 Statement-aware coverage instrumentation - dense one-liner procedures now report honest branch coverage instead of a false 0%. - A procedure written with an IF, its THEN body, and its ELSE all on one physical line (or several statements separated by ; on one line) previously defeated the line-based coverage walker: the branch arms shared the predicate's line, so none could be measured (0% branch) even though the generated tests exercised them all. - A new normalization pass (run before instrumentation) reformats such lines onto canonical one-statement-per-line form so every arm is measured. It is quote / comment / bracket / paren / CASE aware (a CASE expression's WHEN/THEN/ELSE/END is never mistaken for control flow), idempotent, and a no-op on already-well-formatted procedures - so it changes nothing for procedures that already measured correctly. - Validated: a dense IF/ELSE procedure went from a false 0% branch to a true 100% (6/6) with no source change; full regression on AdventureWorks2025 (PredicateZoo), a JSON/MERGE/transaction procedure, and a multi-procedure analytics database all unchanged. No C#/CLR change. ## v0.15.5 (beta) - 2026-06-14 Auto-generation now drives JSON-shredding, transaction-managing procedures to full coverage - deterministic "deep-gate" witnesses for the branch shapes the iterative search could not reach. - A new derivation (TestGen.DeriveDeepGateWitnesses) reads the procedure's own structure - the key-lookup SELECT (table, key column/param, the local-to-column map), and the OPENJSON(@param) WITH(...) shred + catalog JOIN + filter - and synthesises a valid JSON parameter literal plus coordinated real-table seeds. It then emits verified witness tests for: parameter NULL-guards, @@ROWCOUNT "not found" checks, key-lookup status scalars (e.g. an "is active" flag), and aggregate gates over a table VARIABLE populated by the JSON shred (e.g. total-due vs a credit-limit column, or a shortage count) - pivoting the seed to the comparand's real source column instead of the un-seedable table variable - plus a happy-path scenario that falls through every gate. - These run BEFORE the iterative search, which now skips any gate already witnessed - so this whole class of procedure is covered deterministically and fast (no per-candidate sweep). - Self-contained witnesses (which provide their own arguments + seeds) no longer get a spurious ExpectException when the procedure catches its own RAISERROR internally. - The generic base tests are also more robust on this proc shape: a parameter consumed by OPENJSON gets valid JSON in the smoke tests (not arbitrary text that breaks parsing); the "raises"/"rejects" error-expectation tests are skipped when the procedure swallows its own errors in a non-rethrowing CATCH; and the OUTPUT constant-skeleton no longer mashes a literal that is a substring of a longer one (e.g. ''SUCCESS'' inside ''FULL_SUCCESS''). - Validated: a complex order-processing proc (OPENJSON shred + window CTEs + MERGE + a self-managed transaction with several rejection paths) goes from a partial result to 100% line (35/35) and 100% branch (6/6), with the whole generated suite green (11 passed / 0 failed / 0 errored / 8 honest skips). PredicateZoo regression on AdventureWorks2025 green (deep-gate derivation is a no-op on procedures without that shape). No C#/CLR change. - The generic boundary "accepts" tests are no longer falsely skipped on a procedure that manages its own transaction: the generation-time probe now recognises that a "mismatching BEGIN and COMMIT" error (266) is the procedure's own transaction control, not a rejected input. - NEW TestGen.RunTests @SchemaName, @ProcName runs a procedure's generated tests and returns pass/fail. It handles a procedure that manages its OWN transactions - which a direct tSQLt.Run cannot, because the procedure's ROLLBACK collapses tSQLt's per-test transaction and FakeTable setup - by running those tests against the transaction-neutralized shadow (reusing the coverage swap; no coverage permission required, it degrades gracefully). Plain procedures run directly. ## Earlier releases Full release history (v0.12.0 back to v0.9.0) is in CHANGES.md and on the GitHub Releases page: https://github.com/unitautogen/unitautogen-public-repo/releases '@ } } } |