Skip to content

test: the EF satellite's queries, keys and round trips run on a real SQL Server - #142

Merged
CaffeinatedCoder merged 3 commits into
release/2.3.0from
test/ef-sql-server
Oct 29, 2026
Merged

CaffeinatedCoder merged 3 commits into
release/2.3.0from
test/ef-sql-server

Conversation

@CaffeinatedCoder

@CaffeinatedCoder CaffeinatedCoder commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Closes #81

Problem

The EF satellite's queries and round trips ran on SQLite and PostgreSQL. SQL Server, where .Value "works in LINQ as it does in memory" is most likely to differ, was only checked for its model. No query, insert or key read-back ever reached a SQL Server, so nothing said what a consumer sees there.

Change

  • SQL Server in a container (SqlServer.cs): SQL Server 2022, one container for the SQL Server collection, a database per class, many models in schemas of their own. It's a plain Testcontainers container started by its log line, so TYPEKIT_MSSQL_IMAGE can name Azure SQL Edge on an arm64 Mac, where 2022 doesn't start under QEMU.
  • SqlServerQueryVariantTests: the whole QueryShapes catalogue (~10k cases). Each case is held to the wrapped type's query on SQL Server (rows, and SQL on a table column), as the SQLite test does through the now-shared AnswersAsTheWrappedType. Then it is held to memory. A difference passes only where SQLite answers the same, where the ValueOrNull() form answers it (null .Value semantics), or where it is a pinned SQL Server fact (Known). Greatest/Least are also checked at compatibility level 160, without a server: the value object's SQL is the wrapped type's.
  • SqlServerKeyVariantTests: every KeyShapes shape × key kind, inserted and read back. Identity and TPC-sequence keys get the wrapped type's numbers. Assigned keys (char, Guid) round-trip.
  • SqlServerRoundTripTests: the PostgreSQL round trips on SQL Server, plus case-insensitive and trailing-space matching and decimal rounding on value objects next to plain columns.
  • Facts KB-048 to KB-054 (plain EF Core, test/CodoMetis.TypeKit.Facts):
    • text compares ignoring case and trailing spaces;
    • a uniqueidentifier orders by its last group;
    • a decimal is decimal(18,2) by default, read back at scale 2 and rounded on write;
    • time holds less than a day: refused in a column, and silently misread from a JSON column (1.02:00:00 → 01:02:00);
    • no MAX or MIN of a bit;
    • Greatest/Least only from compatibility level 160;
    • datetime2 keeps every tick and reads Kind back as Unspecified.
  • Nothing in src/. Every difference is the wrapped type's too, so none called for a change there. The EF README gets an On SQL Server section with the ones a consumer meets, plus seven claims (E17-*).
  • Catalogue values: text and char now mix case (Bravo, alpha), and the Guids ascend by their first group, so a collation or Guid order can't match memory by accident. This exposed the SQLite test's Greatest/Least stand-in comparing strings by culture. It now compares ordinally, as the value object and SQLite do.
  • CI: the Windows and macOS legs now leave out every class with the trait Needs=Docker (--filter-not-trait): the PostgreSQL round trips and the SQL Server classes and facts. Linux runs them all. CONTRIBUTING says how to run them locally.

Tests

  • Locally on Azure SQL Edge: the EF project passes (20,142 passed, 915 skipped), Facts 105 passed, Oracles, Conventions, CiLanes and docs-query check are clean. CI's Linux leg runs SQL Server 2022, the image the facts pin.
  • Oracles: SqlServerQueryVariantTests and SqlServerKeyVariantTests are registered. The new seed column-cast-not-re-typed is caught: 2,978 of 10,071 cases fail. ushort-key-not-generated is caught by the key leg: 10 of 170 fail.
  • The guard is load-bearing: dropping the Guid-order fact from Known fails 141 Guid cases.

🤖 Generated with Claude Code

CaffeinatedCoder and others added 2 commits October 29, 2026 14:42
…SQL Server

The query catalogue (QueryShapes) and the key catalogue (KeyShapes) run on SQL Server 2022 in a
container, as do the round trips the PostgreSQL class makes. Each query over a value object is held
to the same query over the wrapped type there, and then to memory: a difference from memory passes
only where SQLite answers the same (a relational trait, such as a null .Value that is a NULL in SQL),
where the same query through ValueOrNull() answers it, or where it is a fact of SQL Server's pinned in
design/knowledge with a test of plain EF Core (KB-048 to KB-054): text compared ignoring case and
trailing spaces, a uniqueidentifier ordered by its last group, decimal(18,2) by default, time under a
day (refused in a column, misread from JSON), no MAX of a bit, Greatest and Least only from
compatibility level 160, datetime2 reading a DateTime back as Unspecified. No difference called for a
change in src/: a value object does on SQL Server what its wrapped type does. The EF README states
the ones a consumer meets.

The catalogue's text, char and Guid values now mix case and ascend by the Guid's first group, so a
collation or a uniqueidentifier order cannot match memory by accident. That showed the SQLite test's
stand-in for Greatest and Least comparing strings by the culture, where the value object's generated
comparison and SQLite's max are ordinal; it compares text ordinally now.

The container is a plain Testcontainers one, started by its log line, so TYPEKIT_MSSQL_IMAGE can name
Azure SQL Edge, which runs natively on an arm64 Mac where 2022 does not start under QEMU. The classes
that need Docker carry the trait Needs=Docker, which CI's Windows and macOS legs leave out, the
PostgreSQL round trips included. SqlServerQueryVariantTests and SqlServerKeyVariantTests are oracles,
caught by a new seed (a column cast instead of re-typed) and by the ushort key seed.

Closes #81

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CaffeinatedCoder CaffeinatedCoder added this to the 2.3.0 milestone Oct 29, 2026
@CaffeinatedCoder CaffeinatedCoder added tests Adds or changes tests only (tests, probes, harnesses); no library code package/efcore Affects CodoMetis.TypeKit.EntityFrameworkCore labels Oct 29, 2026
…odoMetis.TypeKit into test/ef-sql-server

# Conflicts:
#	test/oracles/claims.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package/efcore Affects CodoMetis.TypeKit.EntityFrameworkCore tests Adds or changes tests only (tests, probes, harnesses); no library code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant