Skip to content

Commit 6058a75

Browse files
committed
TPU tests for enum-mapping.
1 parent e428e11 commit 6058a75

4 files changed

Lines changed: 167 additions & 0 deletions

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
module TypeProviderUser.SQLite.TestUserPrimitiveEnum
2+
open NUnit.Framework
3+
open System
4+
open Rezoom.SQL
5+
open TypeProviderUser.UserTypes
6+
7+
// End-to-end coverage for mapping CLR enums via the user-type pipeline.
8+
// Two flavors:
9+
// * FavoriteColor — F# enum (System.Enum subtype) mapped to string via
10+
// ToString / Enum.Parse. Underlying storage is human-readable.
11+
// * DateTimeKind — BCL enum mapped to int via the cast operator.
12+
// Underlying storage is the raw enum integer value.
13+
//
14+
// Each flavor gets the same three-test shape used for FileHash in
15+
// TestUserPrimitiveByteArray: roundtrip, parameter equality, and optional
16+
// parameter equality. Together that exercises the parameter-binding path,
17+
// the result-set materialization path, and the option-wrapping path.
18+
19+
// --- FavoriteColor (ToString / Enum.Parse, string-underlying) ------------
20+
21+
type InsertAndSelectColors = SQL<"""
22+
insert into ColorRows(Color) values(@c1);
23+
insert into ColorRows(Color) values(@c2);
24+
select Color from ColorRows order by Id;
25+
""">
26+
27+
[<Test>]
28+
let ``select roundtrips FavoriteColor values via ToString/Enum.Parse mapping`` () =
29+
let results =
30+
InsertAndSelectColors.Command(FavoriteColor.Red, FavoriteColor.Blue)
31+
|> runOnTestData
32+
Assert.AreEqual(2, results.Count)
33+
Assert.AreEqual(FavoriteColor.Red, results.[0].Color)
34+
Assert.AreEqual(FavoriteColor.Blue, results.[1].Color)
35+
36+
type FindColorByParameter = SQL<"""
37+
insert into ColorRows(Color) values(@seed1);
38+
insert into ColorRows(Color) values(@seed2);
39+
select Color from ColorRows where Color = @needle;
40+
""">
41+
42+
[<Test>]
43+
let ``select with FavoriteColor parameter equality returns the matching row only`` () =
44+
let target = FavoriteColor.Red
45+
let other = FavoriteColor.Blue
46+
// Rezoom orders Command args alphabetically by name: needle, seed1, seed2.
47+
let results = FindColorByParameter.Command(target, other, target) |> runOnTestData
48+
Assert.AreEqual(1, results.Count)
49+
Assert.AreEqual(target, results.[0].Color)
50+
51+
type FindColorByOptionalParameter = SQL<"""
52+
insert into ColorRows(Color) values(@seed1);
53+
insert into ColorRows(Color) values(@seed2);
54+
select Color from ColorRows where Color = @needle or @needle is null;
55+
""">
56+
57+
[<Test>]
58+
let ``select with optional FavoriteColor parameter filters when Some and returns all when None`` () =
59+
let target = FavoriteColor.Red
60+
let other = FavoriteColor.Blue
61+
// Command args alphabetical: needle, seed1, seed2.
62+
let withSome =
63+
FindColorByOptionalParameter.Command(Some target, target, other)
64+
|> runOnTestData
65+
Assert.AreEqual(1, withSome.Count)
66+
Assert.AreEqual(target, withSome.[0].Color)
67+
let withNone =
68+
FindColorByOptionalParameter.Command(None, target, other)
69+
|> runOnTestData
70+
Assert.AreEqual(2, withNone.Count)
71+
72+
// --- DateTimeKind (int unwrap, int-underlying) ---------------------------
73+
74+
type InsertAndSelectKinds = SQL<"""
75+
insert into KindRows(Kind) values(@k1);
76+
insert into KindRows(Kind) values(@k2);
77+
insert into KindRows(Kind) values(@k3);
78+
select Kind from KindRows order by Id;
79+
""">
80+
81+
[<Test>]
82+
let ``select roundtrips DateTimeKind values via raw int mapping`` () =
83+
let results =
84+
InsertAndSelectKinds.Command
85+
(DateTimeKind.Utc, DateTimeKind.Local, DateTimeKind.Unspecified)
86+
|> runOnTestData
87+
Assert.AreEqual(3, results.Count)
88+
Assert.AreEqual(DateTimeKind.Utc, results.[0].Kind)
89+
Assert.AreEqual(DateTimeKind.Local, results.[1].Kind)
90+
Assert.AreEqual(DateTimeKind.Unspecified, results.[2].Kind)
91+
92+
type FindKindByParameter = SQL<"""
93+
insert into KindRows(Kind) values(@seed1);
94+
insert into KindRows(Kind) values(@seed2);
95+
select Kind from KindRows where Kind = @needle;
96+
""">
97+
98+
[<Test>]
99+
let ``select with DateTimeKind parameter equality returns the matching row only`` () =
100+
let target = DateTimeKind.Utc
101+
let other = DateTimeKind.Local
102+
// Command args alphabetical: needle, seed1, seed2.
103+
let results = FindKindByParameter.Command(target, other, target) |> runOnTestData
104+
Assert.AreEqual(1, results.Count)
105+
Assert.AreEqual(target, results.[0].Kind)
106+
107+
type FindKindByOptionalParameter = SQL<"""
108+
insert into KindRows(Kind) values(@seed1);
109+
insert into KindRows(Kind) values(@seed2);
110+
select Kind from KindRows where Kind = @needle or @needle is null;
111+
""">
112+
113+
[<Test>]
114+
let ``select with optional DateTimeKind parameter filters when Some and returns all when None`` () =
115+
let target = DateTimeKind.Utc
116+
let other = DateTimeKind.Local
117+
// Command args alphabetical: needle, seed1, seed2.
118+
let withSome =
119+
FindKindByOptionalParameter.Command(Some target, target, other)
120+
|> runOnTestData
121+
Assert.AreEqual(1, withSome.Count)
122+
Assert.AreEqual(target, withSome.[0].Kind)
123+
let withNone =
124+
FindKindByOptionalParameter.Command(None, target, other)
125+
|> runOnTestData
126+
Assert.AreEqual(2, withNone.Count)

src/TypeProviderUsers/TypeProviderUser.SQLite/TypeProviderUser.SQLite.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<Compile Include="TestRowTypeInterfaces.fs" />
1818
<Compile Include="TestUserTypeAnnotations.fs" />
1919
<Compile Include="TestUserPrimitiveByteArray.fs" />
20+
<Compile Include="TestUserPrimitiveEnum.fs" />
2021
<Compile Include="TestPickles.fs" />
2122
<Compile Include="TestMigrateConnectionString.fs" />
2223
<Compile Include="Program.fs" />

src/TypeProviderUsers/TypeProviderUser.SQLite/V1.model.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,13 @@ create table HashedBlobs
3838
, Hash FileHash
3939
);
4040

41+
create table ColorRows
42+
( Id int primary key autoincrement
43+
, Color FavoriteColor
44+
);
45+
46+
create table KindRows
47+
( Id int primary key autoincrement
48+
, Kind DateTimeKind
49+
);
50+

src/TypeProviderUsers/TypeProviderUser.UserTypes/Library.fs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,36 @@ module Extensions =
1111
static member FromPrimitive(s : string) =
1212
System.TimeOnly.ParseExact(s, "o")
1313

14+
// --- Enum fixtures -------------------------------------------------------
15+
//
16+
// Two different ways of routing a CLR enum through the user-type pipeline:
17+
// FavoriteColor — user-defined F# enum, mapped to string via ToString /
18+
// Enum.Parse so storage is human-readable ("Red", "Blue").
19+
// DateTimeKind — BCL enum we cannot edit, mapped to its underlying int
20+
// value via the cast operator. Demonstrates that the same
21+
// external-static-class pattern that handles BCL classes
22+
// also handles BCL enums.
23+
//
24+
// F# enums compile to CLR enums (System.Enum subtypes), distinct from F#
25+
// single-case DUs which compile to class hierarchies. So findSingleCaseDU
26+
// will return None for these and the loader falls through to the explicit
27+
// ToPrimitive/FromPrimitive static-class path.
28+
29+
type FavoriteColor =
30+
| Red = 0
31+
| Green = 1
32+
| Blue = 2
33+
34+
type FavoriteColorMapping() =
35+
static member ToPrimitive(c : FavoriteColor) : string = c.ToString()
36+
static member FromPrimitive(s : string) : FavoriteColor =
37+
System.Enum.Parse<FavoriteColor>(s)
38+
39+
type DateTimeKindMapping() =
40+
static member ToPrimitive(k : System.DateTimeKind) : int = int k
41+
static member FromPrimitive(i : int) : System.DateTimeKind =
42+
enum<System.DateTimeKind> i
43+
1444
// --- Fixtures for the Rezoom.SQL.Annotations attribute pipeline ----------
1545

1646
/// Single-case DU with a type-level RawBackendSQLType attribute. The

0 commit comments

Comments
 (0)