@@ -9,23 +9,27 @@ namespace SqlServerSimulator;
99/// name-resolution surface (<see cref="Collation.TryGet"/> /
1010/// <see cref="Collation.IsRecognized"/>) are exercised in the public
1111/// <c>CollationBehaviorTests</c> / <c>CollationMetadataTests</c> /
12- /// <c>LikeTests</c>; this file keeps only the dormant comparers
13- /// (<see cref="Collation.Latin1General100CiAs"/>,
14- /// <see cref="Collation.Latin1GeneralCiAs"/>,
15- /// <see cref="Collation.Latin1GeneralCsAs"/>,
16- /// <see cref="Collation.Latin1GeneralBin"/>) and the internal-only null
17- /// handling of <see cref="Collation.Default"/>'s
18- /// <see cref="IComparer{T}"/> / <see cref="IEqualityComparer{T}"/>
19- /// contracts. The dormant algorithms exist in the code but aren't called
20- /// from any public SQL site (every string op outside the LIKE
21- /// case-sensitivity flag still goes through <see cref="Collation.Default"/>
22- /// — see <c>docs/claude/database-options.md</c>); the tests pin the
23- /// dormant contract so the algorithms behave correctly once routing
24- /// lands.
12+ /// <c>LikeTests</c>; this file keeps the non-default-collation algorithm
13+ /// contracts and the internal-only null handling of
14+ /// <see cref="Collation.Default"/>'s <see cref="IComparer{T}"/> /
15+ /// <see cref="IEqualityComparer{T}"/> contracts. The non-default
16+ /// algorithms exist in the code but aren't called from any public SQL
17+ /// site (every string op outside the LIKE case-sensitivity flag still
18+ /// goes through <see cref="Collation.Default"/> — see
19+ /// <c>docs/claude/database-options.md</c>); the tests pin the contract
20+ /// so the algorithms behave correctly once routing lands.
2521/// </summary>
2622[ TestClass ]
2723public sealed class CollationTests
2824{
25+ private static readonly Collation Latin1General100CiAs = Collation . TryGet ( "Latin1_General_100_CI_AS" ) ! ;
26+
27+ private static readonly Collation Latin1GeneralCiAs = Collation . TryGet ( "Latin1_General_CI_AS" ) ! ;
28+
29+ private static readonly Collation Latin1GeneralCsAs = Collation . TryGet ( "Latin1_General_CS_AS" ) ! ;
30+
31+ private static readonly Collation Latin1GeneralBin = Collation . TryGet ( "Latin1_General_BIN" ) ! ;
32+
2933 // ---- SQL_Latin1_General_CP1_CI_AS — internal-only contracts ----
3034
3135 /// <summary>
@@ -53,16 +57,16 @@ public void Sql_NullHandling()
5357 [ TestMethod ]
5458 public void Win100_AsciiCaseFolding_EqualAndOrderedSame ( )
5559 {
56- IsTrue ( Collation . Latin1General100CiAs . Equals ( "abc" , "ABC" ) ) ;
57- AreEqual ( 0 , Collation . Latin1General100CiAs . Compare ( "abc" , "ABC" ) ) ;
58- AreEqual ( Collation . Latin1General100CiAs . GetHashCode ( "abc" ) , Collation . Latin1General100CiAs . GetHashCode ( "ABC" ) ) ;
60+ IsTrue ( Latin1General100CiAs . Equals ( "abc" , "ABC" ) ) ;
61+ AreEqual ( 0 , Latin1General100CiAs . Compare ( "abc" , "ABC" ) ) ;
62+ AreEqual ( Latin1General100CiAs . GetHashCode ( "abc" ) , Latin1General100CiAs . GetHashCode ( "ABC" ) ) ;
5963 }
6064
6165 [ TestMethod ]
6266 public void Win100_AccentSensitive ( )
6367 {
64- IsFalse ( Collation . Latin1General100CiAs . Equals ( "e" , "é" ) ) ;
65- AreNotEqual ( 0 , Collation . Latin1General100CiAs . Compare ( "e" , "é" ) ) ;
68+ IsFalse ( Latin1General100CiAs . Equals ( "e" , "é" ) ) ;
69+ AreNotEqual ( 0 , Latin1General100CiAs . Compare ( "e" , "é" ) ) ;
6670 }
6771
6872 [ TestMethod ]
@@ -72,16 +76,16 @@ public void Win100_ApostropheIsPrimaryWeightZero_InSort()
7276 // MIN of ('Aaronsburg', "'Aiea") is 'Aaronsburg' under
7377 // Latin1_General_100_CI_AS because the apostrophe drops out of
7478 // the primary sort key, leaving "Aiea" > "Aaronsburg".
75- IsLessThan ( 0 , Collation . Latin1General100CiAs . Compare ( "Aaronsburg" , "'Aiea" ) ) ;
76- AreEqual ( 0 , Collation . Latin1General100CiAs . Compare ( "'A" , "A" ) ) ;
77- AreEqual ( 0 , Collation . Latin1General100CiAs . Compare ( "O'Brien" , "OBrien" ) ) ;
79+ IsLessThan ( 0 , Latin1General100CiAs . Compare ( "Aaronsburg" , "'Aiea" ) ) ;
80+ AreEqual ( 0 , Latin1General100CiAs . Compare ( "'A" , "A" ) ) ;
81+ AreEqual ( 0 , Latin1General100CiAs . Compare ( "O'Brien" , "OBrien" ) ) ;
7882 }
7983
8084 [ TestMethod ]
8185 public void Win100_HyphenIsPrimaryWeightZero_InSort ( )
8286 {
83- AreEqual ( 0 , Collation . Latin1General100CiAs . Compare ( "co-op" , "coop" ) ) ;
84- AreEqual ( 0 , Collation . Latin1General100CiAs . Compare ( "re-do" , "redo" ) ) ;
87+ AreEqual ( 0 , Latin1General100CiAs . Compare ( "co-op" , "coop" ) ) ;
88+ AreEqual ( 0 , Latin1General100CiAs . Compare ( "re-do" , "redo" ) ) ;
8589 }
8690
8791 [ TestMethod ]
@@ -90,27 +94,27 @@ public void Win100_Equality_IsStrictAboutSymbols_NotJustSort()
9094 // Probe-confirmed: 'OBrien' = 'O''Brien' returns 0 even under
9195 // Windows-100 CI_AS. The primary-weight-zero treatment only
9296 // applies to sort/MIN/MAX, not to '='.
93- IsFalse ( Collation . Latin1General100CiAs . Equals ( "O'Brien" , "OBrien" ) ) ;
94- IsFalse ( Collation . Latin1General100CiAs . Equals ( "'A" , "A" ) ) ;
95- IsFalse ( Collation . Latin1General100CiAs . Equals ( "co-op" , "coop" ) ) ;
97+ IsFalse ( Latin1General100CiAs . Equals ( "O'Brien" , "OBrien" ) ) ;
98+ IsFalse ( Latin1General100CiAs . Equals ( "'A" , "A" ) ) ;
99+ IsFalse ( Latin1General100CiAs . Equals ( "co-op" , "coop" ) ) ;
96100 }
97101
98102 [ TestMethod ]
99103 public void Win100_HashCode_AgreesWithEquals ( )
100104 {
101- AreEqual ( Collation . Latin1General100CiAs . GetHashCode ( "AbC" ) , Collation . Latin1General100CiAs . GetHashCode ( "abc" ) ) ;
105+ AreEqual ( Latin1General100CiAs . GetHashCode ( "AbC" ) , Latin1General100CiAs . GetHashCode ( "abc" ) ) ;
102106 // And differs for strings the equality side distinguishes.
103- AreNotEqual ( Collation . Latin1General100CiAs . GetHashCode ( "O'Brien" ) , Collation . Latin1General100CiAs . GetHashCode ( "OBrien" ) ) ;
107+ AreNotEqual ( Latin1General100CiAs . GetHashCode ( "O'Brien" ) , Latin1General100CiAs . GetHashCode ( "OBrien" ) ) ;
104108 }
105109
106110 [ TestMethod ]
107111 public void Win100_NullHandling ( )
108112 {
109- IsTrue ( Collation . Latin1General100CiAs . Equals ( null , null ) ) ;
110- IsFalse ( Collation . Latin1General100CiAs . Equals ( null , "x" ) ) ;
111- AreEqual ( 0 , Collation . Latin1General100CiAs . Compare ( null , null ) ) ;
112- IsLessThan ( 0 , Collation . Latin1General100CiAs . Compare ( null , "x" ) ) ;
113- IsGreaterThan ( 0 , Collation . Latin1General100CiAs . Compare ( "x" , null ) ) ;
113+ IsTrue ( Latin1General100CiAs . Equals ( null , null ) ) ;
114+ IsFalse ( Latin1General100CiAs . Equals ( null , "x" ) ) ;
115+ AreEqual ( 0 , Latin1General100CiAs . Compare ( null , null ) ) ;
116+ IsLessThan ( 0 , Latin1General100CiAs . Compare ( null , "x" ) ) ;
117+ IsGreaterThan ( 0 , Latin1General100CiAs . Compare ( "x" , null ) ) ;
114118 }
115119
116120 // ---- Latin1_General_CI_AS (Windows-style pre-v100) ----
@@ -122,21 +126,21 @@ public void Win80_BehavesLikeWin100_ForAsciiAndLatin1()
122126 // v100 are identical (the v100 update changed ordering for non-
123127 // Latin scripts and a handful of newly-added supplementary code
124128 // points; none reach the regression bar).
125- IsTrue ( Collation . Latin1GeneralCiAs . Equals ( "abc" , "ABC" ) ) ;
126- AreEqual ( 0 , Collation . Latin1GeneralCiAs . Compare ( "'A" , "A" ) ) ;
127- IsFalse ( Collation . Latin1GeneralCiAs . Equals ( "'A" , "A" ) ) ;
128- IsLessThan ( 0 , Collation . Latin1GeneralCiAs . Compare ( "Aaronsburg" , "'Aiea" ) ) ;
129+ IsTrue ( Latin1GeneralCiAs . Equals ( "abc" , "ABC" ) ) ;
130+ AreEqual ( 0 , Latin1GeneralCiAs . Compare ( "'A" , "A" ) ) ;
131+ IsFalse ( Latin1GeneralCiAs . Equals ( "'A" , "A" ) ) ;
132+ IsLessThan ( 0 , Latin1GeneralCiAs . Compare ( "Aaronsburg" , "'Aiea" ) ) ;
129133 }
130134
131135 [ TestMethod ]
132136 public void Win80_HashCode_AgreesWithEquals ( )
133- => AreEqual ( Collation . Latin1GeneralCiAs . GetHashCode ( "AbC" ) , Collation . Latin1GeneralCiAs . GetHashCode ( "abc" ) ) ;
137+ => AreEqual ( Latin1GeneralCiAs . GetHashCode ( "AbC" ) , Latin1GeneralCiAs . GetHashCode ( "abc" ) ) ;
134138
135139 // ---- Latin1_General_CS_AS ----
136140
137141 [ TestMethod ]
138142 public void CsAs_AccentSensitive ( )
139- => IsFalse ( Collation . Latin1GeneralCsAs . Equals ( "e" , "é" ) ) ;
143+ => IsFalse ( Latin1GeneralCsAs . Equals ( "e" , "é" ) ) ;
140144
141145 // ---- Latin1_General_BIN ----
142146
@@ -146,9 +150,11 @@ public void Bin_StrictCodepoint_DistinguishesNfdAndNfc()
146150 // NFC = single precomposed U+00E9; NFD = base 'e' + combining
147151 // U+0301. Ordinal compare treats them as distinct byte sequences;
148152 // CompareInfo-based comparers (Sql, Win100, CsAs) fold them.
153+ // Spelled with escapes so editor / tool normalization can't collapse
154+ // the two literals into the same encoded form.
149155 const string nfc = "é" ;
150156 const string nfd = "é" ;
151- IsFalse ( Collation . Latin1GeneralBin . Equals ( nfc , nfd ) ) ;
157+ IsFalse ( Latin1GeneralBin . Equals ( nfc , nfd ) ) ;
152158 IsTrue ( Collation . Default . Equals ( nfc , nfd ) ) ;
153159 }
154160}
0 commit comments