rastrillo / fiesta Public

Spy on showPicker in the calendar's fallback leg, and read the vocabulary off the attribute as JSON text in a drive

The /nocal leg of driveCalendarOpen waited 300 ms and then checked
for the absence of a dialog, which nothing without calendar.js could
have drawn: a click handler that returned early would have passed. A
counting spy now stands in for HTMLInputElement.prototype.showPicker
before the press, and the leg requires one call. The handler calls it
synchronously, so the wait is gone. Dropping the native.showPicker()
line in a scratch copy fails the leg with "called showPicker 0 times".

TestAttributeWordsReachTheParser serves the Spanish page with no table
and es.json's date-words on the input as JSON text, the form a
server-rendered page carries, and requires typing mañana to arm a
reading and every label to be the English fallback. The two Spanish
drives share one page builder and one drive. Inverting the typeof test
on date-words in a scratch copy fails both drives on the wait for an
armed reading. TestTheTableFillsAMissingAttribute gains the lang="de"
document with only an es table, the fallback again, and passes no
registry, since the word scenarios build their own tables.

The cap comment's arithmetic is restated: +1.7 KB net of +4.4 KB
written and 2.75 KB removed, the 1.0 KB of code already net of attr,
and 78 KB as the next whole step with 0.4 KB to spare. Plan ids are
out of the code comments in the files this task touched; the comments
say what the constraint is instead. The stale ui/select_node.mjs path
on the line the first commit edited is check/node/select_node.mjs.

Summary

driveCalendarOpen's fallback leg counts showPicker calls through a prototype spy, no fixed wait; TestAttributeWordsReachTheParser (date-words as attribute JSON text, no table, English fallbacks); a lang with no table scenario in TestTheTableFillsAMissingAttribute, with no unused registry; the cap comment's arithmetic corrected; plan ids removed from comments; the select.js driver path.
Agent notes
Task 6 fix round 1. Controls in a scratch copy: deleting native.showPicker() fails TestTheCalendarOpensThroughFiestaCalendar (0 calls, want 1); inverting the date-words typeof test fails TestTableOnlyStringsReachTheScreen and TestAttributeWordsReachTheParser. Untagged covering run: 12 tests; browser: 3 drives. make ci exit 0.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 298e10692ebb1222006c8791aa5f7c82309c82c3 parent efb5b27
6 files changed, +161 −87
  • check/calendar_browser_test.go +13 −6
  • check/datetime_test.go +13 −12
  • check/node/strings_node.mjs +8 −4
  • check/strings_browser_test.go +108 −52
  • check/strings_test.go +18 −12
  • js/select.js +1 −1

CI passed — run details

CI log
=== gofmt ===
=== no-rastrillo ===
go test -run '^(TestFiestaNeverImportsRastrillo|TestThePublicPackagesLinkNoBrowser)$' -count=1 .
ok  	amadan.net/rastrillo/fiesta	0.063s
=== suite ===
--- shard 0 of 6 ---
==> shard 0 of 6: make root
go build ./...
go vet ./...
FIESTA_TEST_REQUIRE_NODE=1 go test -count=1 ./...
ok  	amadan.net/rastrillo/fiesta	0.185s
ok  	amadan.net/rastrillo/fiesta/check	1.461s
ok  	amadan.net/rastrillo/fiesta/example	0.136s
ok  	amadan.net/rastrillo/fiesta/internal/axe	0.013s
?   	amadan.net/rastrillo/fiesta/internal/harness	[no test files]
ok  	amadan.net/rastrillo/fiesta/internal/markup	0.013s
ok  	amadan.net/rastrillo/fiesta/internal/nodetest	0.298s
--- shard 1 of 6 ---
==> shard 1 of 6: make staticcheck
go run honnef.co/go/tools/cmd/staticcheck@v0.8.2 -tags browser ./...
--- shard 2 of 6 ---
==> shard 2 of 6: make govulncheck
go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./...
=== Symbol Results ===

No vulnerabilities found.

Your code is affected by 0 vulnerabilities.
This scan also found 0 vulnerabilities in packages you import and 5
vulnerabilities in modules you require, but your code doesn't appear to call
these vulnerabilities.
Use '-show verbose' for more details.
--- shard 3 of 6 ---
==> shard 3 of 6: make gitleaks
go run github.com/zricethezav/gitleaks/v8@v8.30.1 git --no-banner --redact --log-opts='--full-history --diff-filter=tuxdb HEAD' .
9:43AM INF Unknown SCM platform. Use --platform to include links in findings. host=amadan.net
9:43AM INF 1 commits scanned.
9:43AM INF scanned ~3062933 bytes (3.06 MB) in 1.67s
9:43AM INF no leaks found
--- shard 4 of 6 ---
==> shard 4 of 6: make browser.internal.harness
./hack/gotest.sh browser 'internal.harness'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
ok  	amadan.net/rastrillo/fiesta/internal/harness	7.898s
--- shard 5 of 6 ---
==> shard 5 of 6: make browser.check
./hack/gotest.sh browser 'check'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
ok  	amadan.net/rastrillo/fiesta/check	8.801s
diff --git a/check/calendar_browser_test.go b/check/calendar_browser_test.go
index dbfbc1e..b4aed25 100644
--- a/check/calendar_browser_test.go
+++ b/check/calendar_browser_test.go
@@ -21,8 +21,8 @@ import (
// loudly if it moves: the button quietly falls back to the browser's
// own picker, which is the control the overlay replaced. This drive
// holds the rename end to end, and driveCalendarOpen is its body,
-// standalone so Task 12 can run it against the release's scripts on a
-// rig of its own built from calendarPages.
+// standalone so the release build's tests can run it against the
+// stripped scripts on a rig of their own built from calendarPages.
// calendarPages is the drive's two pages: "/" is field-date's default
// state, from the manifest, on the shared fixture page, which links
@@ -112,11 +112,18 @@ func driveCalendarOpen(t *testing.T, rig *harness.Rig) {
if fallback.Haspopup != "" {
t.Errorf("without calendar.js, the button's aria-haspopup is %q, want none: it hands over to the browser's own panel", fallback.Haspopup)
}
- // The press reaches native.showPicker(), which opens the browser's
- // own panel or throws (caught) where there is none. Either way the
- // page draws no dialog of its own.
+ // The press reaches native.showPicker(), the browser's own panel,
+ // and that is the only thing it reaches: a counting spy stands in
+ // for the method (the handler calls it synchronously, so there is
+ // nothing to wait for), and the page draws no dialog of its own. A
+ // handler that returned early would leave the count at zero.
+ mustRun(t, ctx, chromedp.Evaluate(`(() => { window.__fiestaPicked = 0; HTMLInputElement.prototype.showPicker = function () { window.__fiestaPicked++; }; return true; })()`, nil))
mustRun(t, ctx, chromedp.Click(`[rst-dtp-pick]`, chromedp.ByQuery))
- time.Sleep(300 * time.Millisecond)
+ var picked int
+ mustRun(t, ctx, chromedp.Evaluate(`window.__fiestaPicked`, &picked))
+ if picked != 1 {
+ t.Errorf("without calendar.js, the press called showPicker %d times; want once, the fallback to the native picker", picked)
+ }
var pressed calendarOpening
at(t, ctx, calendarOpeningJS, &pressed)
if pressed.Dialogs != 0 || pressed.Cells != 0 {
diff --git a/check/datetime_test.go b/check/datetime_test.go
index d7bd282..d8cf619 100644
--- a/check/datetime_test.go
+++ b/check/datetime_test.go
@@ -441,18 +441,19 @@ func TestDatetimeContract(t *testing.T) {
// and 22KB is that; one file at 96KB is not, which is the whole
// reason the split came first and the raise second.
//
- // 76KB → 78KB, by the string tables (Fiesta Task 6). SEED's file
- // sat 45 bytes under the cap, so anything at all raised it. What
- // arrived is +1.7KB: fiestaPickLang and fiestaWord, the lookup that
- // reads a label off the attribute, then the page's table, then the
- // fallback, about 1.0KB of code with their exports and the
- // date-words branch that takes the table's object or the
- // attribute's JSON; and about 0.7KB of prose, the header's strings
- // paragraph rewritten for the new order, the seven quick-pick
- // attributes written out where "quick-*" stood, and the section
- // comment. The old attr helper and its seventeen calls went, which
- // is the 0.2KB the raise is smaller than the addition. The copy in
- // select.js is the same bytes; see TestTheTwoLookupsAreTheSame.
+ // 76KB → 78KB, by the string tables. The file sat 45 bytes under
+ // the cap, so anything at all raised it. What arrived is +1.7KB
+ // net (+4.4KB written, 2.75KB removed): fiestaPickLang and
+ // fiestaWord, the lookup that reads a label off the attribute,
+ // then the page's table, then the fallback, about 1.0KB of code
+ // once the old attr helper and its seventeen calls are netted off,
+ // with the exports and the date-words branch that takes the
+ // table's object or the attribute's JSON; and about 0.7KB of prose,
+ // the header's strings paragraph rewritten for the new order, the
+ // seven quick-pick attributes written out where "quick-*" stood,
+ // and the section comment. 78KB is the next whole step that holds
+ // it, with 0.4KB to spare. The copy in select.js is the same bytes;
+ // see TestTheTwoLookupsAreTheSame.
if n := len(raw); n > 78*1024 {
t.Fatalf("datetime.js is %d bytes; split something out before it stops being readable", n)
}
diff --git a/check/node/strings_node.mjs b/check/node/strings_node.mjs
index c17ff68..06afae9 100644
--- a/check/node/strings_node.mjs
+++ b/check/node/strings_node.mjs
@@ -10,10 +10,13 @@
// object: "pick", fiestaPickLang's answer for each tag on stdin plus
// one for undefined under "<undefined>", against a registry holding
// an (empty) table per tag named; and "word", fiestaWord's answer in
-// four scenarios on a stub element in a lang="es" document whose table
-// says "Tabla": "both" (attribute "Atributo" and the table), "empty"
-// (an empty attribute and the table), "table" (no attribute) and
-// "neither" (no attribute, no table, so the fallback "English").
+// five scenarios on a stub element, four in a lang="es" document whose
+// table says "Tabla": "both" (attribute "Atributo" and the table),
+// "empty" (an empty attribute and the table), "table" (no attribute)
+// and "neither" (no attribute, no table, so the fallback "English");
+// and "notable", a lang="de" document with only that es table and no
+// attribute, the fallback again. The word scenarios build their own
+// tables, so stdin's registry is for "pick" alone.
//
// The page is the least DOM either script touches on load: a document
// that is still loading, with a root carrying lang, and a self holding
@@ -86,6 +89,7 @@ const out = { pick: {}, word: {} };
out.word.empty = withTable(element({ "data-rst-date-set": "" }), "date-set", "English");
out.word.table = withTable(element({}), "date-set", "English");
out.word.neither = without(element({}), "date-set", "English");
+ out.word.notable = load("de", table).fiestaWord(element({}), "date-set", "English");
}
process.stdout.write(JSON.stringify(out));
diff --git a/check/strings_browser_test.go b/check/strings_browser_test.go
index c22f8b4..d593640 100644
--- a/check/strings_browser_test.go
+++ b/check/strings_browser_test.go
@@ -5,6 +5,7 @@ package check
import (
"context"
"encoding/json"
+ "html"
"net/http"
"strings"
"testing"
@@ -16,73 +17,104 @@ import (
"amadan.net/rastrillo/fiesta/internal/harness"
)
-// The Node tests in strings_test.go hold the lookup on a stub; this
-// holds it on a real page, through real enhancement: a page that
+// The Node tests in strings_test.go hold the lookup on a stub; these
+// hold it on a real page, through real enhancement: a page that
// carries no string attributes at all, only the table, still puts the
-// table's words on screen.
+// table's words on screen; and a page with no table still reads the
+// vocabulary off its attribute, as JSON text, and falls back to the
+// English labels.
-// tableOnlyDoc is a lang="es" page that sets self.fiestaStrings = {es:
-// <es.json>} inline, ahead of the deferred scripts, and carries a date
-// field armed with data-rst-date and a twelve-option select armed with
-// data-rst-select: no data-rst-date-* and no data-rst-select-*
-// attribute anywhere, so every word the two enhancements show has to
-// come out of the table.
-func tableOnlyDoc(t *testing.T, es []byte) string {
+// spanishDoc is a lang="es" page carrying a date field armed with
+// data-rst-date and a twelve-option select armed with data-rst-select,
+// and no data-rst-date-* or data-rst-select-* attribute (asserted)
+// beyond the two this builder adds: with table, an inline
+// <script>self.fiestaStrings = {es: <table>}</script> ahead of the
+// deferred scripts; with words, data-rst-date-words on the input,
+// holding that JSON text.
+func spanishDoc(t *testing.T, table []byte, words string) string {
t.Helper()
var b strings.Builder
- b.WriteString(`<div rst-field><label rst-field-label for="when">Fecha</label><input rst-input id="when" name="when" type="date" data-rst-date></div>` + "\n")
+ b.WriteString(`<div rst-field><label rst-field-label for="when">Fecha</label><input rst-input id="when" name="when" type="date" data-rst-date`)
+ if words != "" {
+ b.WriteString(` data-rst-date-words="` + html.EscapeString(words) + `"`)
+ }
+ b.WriteString(`></div>` + "\n")
b.WriteString(`<div rst-field><label rst-field-label for="city">Ciudad</label><select rst-input id="city" name="city" data-rst-select>`)
for _, city := range []string{"Dublín", "Lisboa", "Madrid", "Berlín", "Roma", "Atenas", "Helsinki", "Reikiavik", "Varsovia", "Zagreb", "Tallin", "La Valeta"} {
b.WriteString(`<option>` + city + `</option>`)
}
b.WriteString(`</select></div>`)
doc := sizingDoc("strings", b.String())
- if strings.Contains(doc, "data-rst-date-") || strings.Contains(doc, "data-rst-select-") {
- t.Fatalf("the table-only page carries a string attribute:\n%s", doc)
+ wantWords := 0
+ if words != "" {
+ wantWords = 1
+ }
+ if strings.Count(doc, "data-rst-date-") != wantWords || strings.Count(doc, "data-rst-date-words") != wantWords || strings.Contains(doc, "data-rst-select-") {
+ t.Fatalf("the page carries a string attribute it should not:\n%s", doc)
}
- es0 := strings.Replace(doc, `<html lang="en"`, `<html lang="es"`, 1)
- if es0 == doc {
+ es := strings.Replace(doc, `<html lang="en"`, `<html lang="es"`, 1)
+ if es == doc {
t.Fatal("the fixture page does not say lang=\"en\" where this test expects to change it")
}
- table := `<script>self.fiestaStrings = {es: ` + string(es) + `};</script>`
- withTable := strings.Replace(es0, `<head>`, `<head>`+table, 1)
- if withTable == es0 {
+ if table == nil {
+ return es
+ }
+ withTable := strings.Replace(es, `<head>`, `<head><script>self.fiestaStrings = {es: `+string(table)+`};</script>`, 1)
+ if withTable == es {
t.Fatal("the fixture page has no <head> to put the table in")
}
return withTable
}
-// TestTableOnlyStringsReachTheScreen: on the table-only page, the
-// date field's set label (the meta on the first reading) is es.json's
-// date-set, typing mañana resolves (the vocabulary came from the
-// table's date-words, not an attribute), the first quick pick is
-// es.json's date-quick-today, and the select's filter placeholder is
-// es.json's select-filter.
-func TestTableOnlyStringsReachTheScreen(t *testing.T) {
+// esStrings is what the two drives read out of es.json.
+type esStrings struct {
+ Set string `json:"date-set"`
+ Today string `json:"date-quick-today"`
+ Filter string `json:"select-filter"`
+ Words json.RawMessage `json:"date-words"`
+}
+
+// loadES reads es.json and checks it can tell the table from the
+// fallback: a table whose strings were the English ones would let
+// either drive pass for the wrong reason.
+func loadES(t *testing.T) ([]byte, esStrings, string) {
+ t.Helper()
es, ok := fiesta.Strings("es")
if !ok {
t.Fatal("no es table")
}
- var want struct {
- Set string `json:"date-set"`
- Today string `json:"date-quick-today"`
- Filter string `json:"select-filter"`
- Words struct {
- Tomorrow string `json:"tomorrow"`
- } `json:"date-words"`
- }
+ var want esStrings
if err := json.Unmarshal(es, &want); err != nil {
t.Fatal(err)
}
- if want.Set == "" || want.Today == "" || want.Filter == "" || want.Words.Tomorrow == "" {
- t.Fatalf("es.json is missing a string this drive reads: %+v", want)
+ var words map[string]string
+ if err := json.Unmarshal(want.Words, &words); err != nil {
+ t.Fatal(err)
+ }
+ if want.Set == "" || want.Today == "" || want.Filter == "" || words["tomorrow"] == "" {
+ t.Fatalf("es.json is missing a string these drives read: %+v", want)
}
if want.Set == "Set" || want.Filter == "Type to filter" {
- t.Fatalf("es.json's strings are the English fallbacks, so this drive could not tell the table from the fallback: %+v", want)
+ t.Fatalf("es.json's strings are the English fallbacks, so these drives could not tell the table from the fallback: %+v", want)
}
- tomorrow := strings.Split(want.Words.Tomorrow, "|")[0]
+ return es, want, strings.Split(words["tomorrow"], "|")[0]
+}
- pages := map[string]string{"/": tableOnlyDoc(t, es)}
+// spanishScreen is what the page shows once both fields are enhanced
+// and tomorrow's word has been typed into the date field: the select's
+// filter placeholder, and the armed reading's set label, its text and
+// the first quick pick's label.
+type spanishScreen struct {
+ Placeholder, Set, Label, Quick string
+}
+
+// driveSpanish serves doc, waits for both enhancements, types tomorrow
+// into the date field and reads the screen. A reading arms the first
+// row; text the parser refused arms nothing, so a vocabulary that did
+// not arrive fails on the wait.
+func driveSpanish(t *testing.T, doc, tomorrow string) spanishScreen {
+ t.Helper()
+ pages := map[string]string{"/": doc}
rig := harness.New(t, func(string) http.Handler { return sizingMux(t, pages) })
ctx, cancel := context.WithTimeout(rig.Context(), 120*time.Second)
defer cancel()
@@ -90,27 +122,33 @@ func TestTableOnlyStringsReachTheScreen(t *testing.T) {
mustRun(t, ctx,
chromedp.Navigate(rig.Origin+"/"),
chromedp.WaitVisible(`[rst-dtp] input[role="combobox"]`, chromedp.ByQuery),
- chromedp.WaitVisible(`[rst-combo] input[role="combobox"]`, chromedp.ByQuery))
-
- var placeholder string
- mustRun(t, ctx, chromedp.Evaluate(`document.querySelector('[rst-combo] input[role="combobox"]').placeholder`, &placeholder))
- if placeholder != want.Filter {
- t.Errorf("the select's filter placeholder reads %q, want es.json's select-filter %q", placeholder, want.Filter)
- }
-
- mustRun(t, ctx,
+ chromedp.WaitVisible(`[rst-combo] input[role="combobox"]`, chromedp.ByQuery),
chromedp.Click(`[rst-dtp] input[role="combobox"]`, chromedp.ByQuery),
chromedp.SendKeys(`[rst-dtp] input[role="combobox"]`, tomorrow, chromedp.ByQuery))
- // A reading arms the first row; text the parser refused arms
- // nothing, so a vocabulary that did not arrive stops here.
settleUntil(t, ctx, `!!document.querySelector('[rst-dtp] [role="option"].is-active [rst-dtp-label]')`)
- var got struct{ Set, Label, Quick string }
+ var got spanishScreen
at(t, ctx, `JSON.stringify({
+ Placeholder: document.querySelector('[rst-combo] input[role="combobox"]').placeholder,
Set: document.querySelector('[rst-dtp] [role="option"].is-active [rst-dtp-set]')?.textContent ?? '',
Label: document.querySelector('[rst-dtp] [role="option"].is-active [rst-dtp-label]')?.textContent ?? '',
Quick: document.querySelector('[rst-dtp] [rst-dtp-quick] [rst-dtp-label]')?.textContent ?? ''})`, &got)
if got.Label == "" {
- t.Errorf("typing %q armed no reading; the table's date-words did not reach the parser", tomorrow)
+ t.Errorf("typing %q armed no reading; the vocabulary did not reach the parser", tomorrow)
+ }
+ rig.Screen("body", "the Spanish page after typing "+tomorrow)
+ return got
+}
+
+// TestTableOnlyStringsReachTheScreen: on the table-only page, the
+// select's filter placeholder is es.json's select-filter, typing
+// mañana resolves (the vocabulary came from the table's date-words,
+// an object, not an attribute), the armed reading's set label is
+// es.json's date-set, and the first quick pick is date-quick-today.
+func TestTableOnlyStringsReachTheScreen(t *testing.T) {
+ es, want, tomorrow := loadES(t)
+ got := driveSpanish(t, spanishDoc(t, es, ""), tomorrow)
+ if got.Placeholder != want.Filter {
+ t.Errorf("the select's filter placeholder reads %q, want es.json's select-filter %q", got.Placeholder, want.Filter)
}
if got.Set != want.Set {
t.Errorf("the date field's set label reads %q, want es.json's date-set %q", got.Set, want.Set)
@@ -118,5 +156,23 @@ func TestTableOnlyStringsReachTheScreen(t *testing.T) {
if got.Quick != want.Today {
t.Errorf("the first quick pick reads %q, want es.json's date-quick-today %q", got.Quick, want.Today)
}
- rig.Screen("body", "table-only strings on a Spanish page")
+}
+
+// TestAttributeWordsReachTheParser is the other way in: no table on
+// the page, and es.json's date-words on the input as JSON text, the
+// form a server-rendered page carries. Typing mañana still resolves,
+// and every label is the script's English fallback, since the page's
+// language has no table and nothing else says otherwise.
+func TestAttributeWordsReachTheParser(t *testing.T) {
+ _, want, tomorrow := loadES(t)
+ got := driveSpanish(t, spanishDoc(t, nil, string(want.Words)), tomorrow)
+ if got.Placeholder != "Type to filter" {
+ t.Errorf("with no table, the select's filter placeholder reads %q, want the fallback", got.Placeholder)
+ }
+ if got.Set != "Set" {
+ t.Errorf("with no table, the date field's set label reads %q, want the fallback", got.Set)
+ }
+ if got.Quick != "Today" {
+ t.Errorf("with no table, the first quick pick reads %q, want the fallback", got.Quick)
+ }
}
diff --git a/check/strings_test.go b/check/strings_test.go
index 0d95c37..b614d34 100644
--- a/check/strings_test.go
+++ b/check/strings_test.go
@@ -176,8 +176,8 @@ func TestEveryLanguageHasEveryKey(t *testing.T) {
}
// lookupScripts are the two scripts that carry the string lookup, each
-// its own copy (F14): every enhancement is one script tag, and a
-// shared file would be a third tag every page had to remember.
+// its own copy: every enhancement is one script tag, and a shared
+// file would be a third tag every page had to remember.
var lookupScripts = []string{"datetime.js", "select.js"}
// stringsReport is what node/strings_node.mjs reports for one script:
@@ -256,16 +256,22 @@ func str(p *string) string {
}
// TestTheTableFillsAMissingAttribute: fiestaWord reads the attribute
-// first, the page's table second, and the fallback last (F1). On a
-// stub element in a lang="es" document whose table says "Tabla": with
-// the attribute "Atributo" and the table both present, the attribute;
+// first, the page's table second, and the fallback last. On a stub
+// element in a lang="es" document whose table says "Tabla": with the
+// attribute "Atributo" and the table both present, the attribute;
// with the attribute empty, the table; with only the table, the
-// table; with neither, the English fallback.
+// table; with neither, the English fallback; and on a lang="de"
+// document with only that es table, no attribute, the fallback too,
+// since a language with no table is not read in another one. The
+// driver builds its own tables for these, so no registry goes over.
func TestTheTableFillsAMissingAttribute(t *testing.T) {
- want := map[string]string{"both": "Atributo", "empty": "Tabla", "table": "Tabla", "neither": "English"}
+ want := map[string]string{"both": "Atributo", "empty": "Tabla", "table": "Tabla", "neither": "English", "notable": "English"}
for _, script := range lookupScripts {
t.Run(script, func(t *testing.T) {
- got := stringsNode(t, script, []string{"en", "es"}, nil).Word
+ got := stringsNode(t, script, nil, nil).Word
+ if len(got) != len(want) {
+ t.Fatalf("the driver ran %d scenarios, want %d: %v", len(got), len(want), got)
+ }
for scenario, w := range want {
g, ok := got[scenario]
if !ok {
@@ -304,10 +310,10 @@ func functionBody(js, name string) string {
return ""
}
-// TestTheTwoLookupsAreTheSame (F14): datetime.js and select.js each
-// carry fiestaPickLang and fiestaWord, so each enhancement stays one
-// script tag. The price of two copies is drift, so the two bodies are
-// held identical, character for character.
+// TestTheTwoLookupsAreTheSame: datetime.js and select.js each carry
+// fiestaPickLang and fiestaWord, so each enhancement stays one script
+// tag. The price of two copies is drift, so the two bodies are held
+// identical, character for character.
func TestTheTwoLookupsAreTheSame(t *testing.T) {
a, b := string(shippedScript(t, "datetime.js")), string(shippedScript(t, "select.js"))
for _, name := range []string{"fiestaPickLang", "fiestaWord"} {
diff --git a/js/select.js b/js/select.js
index f1a1bb6..a2564db 100644
--- a/js/select.js
+++ b/js/select.js
@@ -207,7 +207,7 @@
return table && table[key] !== undefined && table[key] !== "" ? table[key] : fallback;
}
- // The pure half, for ui/select_node.mjs, and the lookup for
+ // The pure half, for check/node/select_node.mjs, and the lookup for
// check/node/strings_node.mjs. A browser has no `module` and never
// takes this branch.
if (typeof module !== "undefined" && module && module.exports) {