| 1 | package xlsx_test |
| 2 | |
| 3 | import ( |
| 4 | "testing" |
| 5 | |
| 6 | "amadan.net/oficina/sheets/internal/sheets/calc" |
| 7 | ) |
| 8 | |
| 9 | // A SECOND opinion on the wildcard criteria, beside the corpus. |
| 10 | // |
| 11 | // These were briefly the ONLY check on wildcards, when LibreOffice |
| 12 | // answered 0 to all of them and that was read as "its profile does not |
| 13 | // do Excel wildcards". The diagnosis was wrong: wildcards are a |
| 14 | // per-document calculation setting, and gencorpus was writing an .ods |
| 15 | // with no <table:calculation-settings>, so LibreOffice fell back to |
| 16 | // ODF's legacy default — regular expressions on, wildcards off. One |
| 17 | // element in ods.go and the same binary answers exactly as Excel does. |
| 18 | // Caught by review, 2026-09-04. |
| 19 | // |
| 20 | // So every case below is now in the LibreOffice corpus too, and this |
| 21 | // file is a cross-check rather than a substitute. It stays because two |
| 22 | // independent engines agreeing is worth more than one, and because the |
| 23 | // mutation test below is the thing that proves the comparison is live. |
| 24 | // It also keeps a record of why the corpus is the primary oracle: the |
| 25 | // substitute is weak, and during that same review excelize was observed |
| 26 | // answering 0 to SUM over a range holding an error and panicking on a |
| 27 | // COUNTIFS shape mismatch. |
| 28 | var wildcardCases = []string{ |
| 29 | `COUNTIF(B1:B3,"t??")`, |
| 30 | `COUNTIF(B1:B3,"t*")`, |
| 31 | `SUMIF(B1:B3,"t*",A1:A3)`, |
| 32 | `COUNTIF(B1:B3,"t?n")`, |
| 33 | `COUNTIF(B1:B3,"*y")`, |
| 34 | `SUMIFS(A1:A3,B1:B3,"t*")`, |
| 35 | `COUNTIFS(A1:A3,">=20",B1:B3,"t*")`, |
| 36 | } |
| 37 | |
| 38 | func TestWildcardCriteriaAgainstExcelize(t *testing.T) { |
| 39 | for _, expr := range wildcardCases { |
| 40 | ours := calc.Eval(mustParseOracle(t, expr), oracleCellEnv) |
| 41 | oa := computeOracleAnswer(t, expr) |
| 42 | if !oa.Available { |
| 43 | t.Errorf("%s: excelize could not answer (%s) — this test has no other "+ |
| 44 | "oracle, so an unavailable one makes it vacuous rather than passing", |
| 45 | expr, oa.Reason) |
| 46 | continue |
| 47 | } |
| 48 | if !agreesWithOracle(ours, oa.Value) { |
| 49 | t.Errorf("%s: ours=%q excelize=%q — investigate before assuming we are "+ |
| 50 | "wrong, but note that LibreOffice's 0 for this expression is a "+ |
| 51 | "profile difference and not a third opinion", |
| 52 | expr, renderCalcValue(ours), oa.Value) |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | // TestTheWildcardOracleIsActuallyComparing is the mutation check. |
| 58 | // |
| 59 | // The test above passes if excelize agrees, and it would also pass with |
| 60 | // an empty case list or a matcher that silently answered nothing. This |
| 61 | // asserts the list is populated and that the comparison is live, by |
| 62 | // running an expression whose answer differs between a working wildcard |
| 63 | // matcher and a literal one. |
| 64 | func TestTheWildcardOracleIsActuallyComparing(t *testing.T) { |
| 65 | if len(wildcardCases) == 0 { |
| 66 | t.Fatal("the wildcard case list is empty; the test above proves nothing") |
| 67 | } |
| 68 | oa := computeOracleAnswer(t, `COUNTIF(B1:B3,"t*")`) |
| 69 | if !oa.Available { |
| 70 | t.Fatal("excelize cannot answer a plain wildcard COUNTIF; the oracle is gone") |
| 71 | } |
| 72 | if oa.Value == "0" { |
| 73 | t.Fatal(`excelize answered 0 to COUNTIF(B1:B3,"t*") — it has stopped treating ` + |
| 74 | `* as a wildcard, so it is no longer an oracle for Excel's semantics ` + |
| 75 | `and this whole file needs re-deciding`) |
| 76 | } |
| 77 | } |
| 78 | |