clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

main
forge / test / scenarios / search-phrases.sh
search-phrases.sh 6.2K
1# The search reads a query the same way in every section: terms split on2# whitespace, a quoted phrase is one term that must appear as written3# (ignoring case, and a run of whitespace in it matching any run), and every4# term must match. Commits, reviews, wiki pages and repos match through5# site/assets/query.ts, as the browser does, and code search's words come6# out the same and find lines the same way.7. "$(dirname "$0")/../lib.sh"8user dami9repo dami/greet "say hello world"10repo dami/other "hello there, world"11clone dami dami/greet "$T/w/dami"12at "$T/w/dami" commit "Fix the search box"13at "$T/w/dami" commit "Search fix for the box"14tick15at "$T/w/dami" git commit -q --allow-empty -m "Tidy the box" -m "This is to fix the search for good."16at "$T/w/dami" commit "box search fix"17printf 'width = height\ndepth = length\ntotal\tcount\nx = 1\ny = 2\n' >"$T/w/dami/sizes.txt"18at "$T/w/dami" commit "Align the columns"19push_as dami "$T/w/dami" origin main20at "$T/w/dami" git switch -q -c dami/wide21at "$T/w/dami" commit "Make the search box wider"22push_as dami "$T/w/dami" origin dami/wide23build24ix=$FORGE_WWW/dami/greet/search.json25exists "$ix"26terms() { node "$T_HOME/test/search-phrases.ts" terms "$@"; }27match() { node "$T_HOME/test/search-phrases.ts" match "$@"; }2829# The parser. A phrase is one term, spaces and all; words are terms of their30# own; an unclosed quote runs to the end, as a phrase; empty quotes (or only31# spaces in them) are no term; a quote inside a word is a character. Code32# search reads the same terms, less any inside another (a line with the33# longer one has it).34ok terms 'fix search'35eq "$(output)" 'fix search => [fix] [search] | code [fix] [search]'36ok terms '"Fix the Search"'37eq "$(output)" '"Fix the Search" => [fix the search] | code [fix the search]'38ok terms '"the search'39eq "$(output)" '"the search => [the search] | code [the search]'40# A run of whitespace in a phrase is kept as one space, which matches any41# run of whitespace (below); spaces at its ends stay, one each.42ok terms '"fix the search"' '" fix "'43eq "$(output)" '"fix the search" => [fix the search] | code [fix the search]44" fix " => [ fix ] | code [ fix ]'45ok terms '""' '" "' '"'46eq "$(output)" '"" => - | code -47" " => - | code -48" => - | code -'49ok terms '"search box" fix' 'fix "search box"'50eq "$(output)" '"search box" fix => [search box] [fix] | code [search box] [fix]51fix "search box" => [fix] [search box] | code [fix] [search box]'52ok terms 'search "search box"' 'Fix FIX'53eq "$(output)" 'search "search box" => [search] [search box] | code [search box]54Fix FIX => [fix] | code [fix]'55ok terms "it's\"" 'a"b c' '"fix"box'56eq "$(output)" "it's\" => [it's\"] | code [it's\"]57a\"b c => [a\"b] [c] | code [a\"b] [c]58\"fix\"box => [fix] [box] | code [fix] [box]"5960# Words: every commit with both, in any order, in the subject or the body.61ok match "$ix" 'fix search'62eq "$(output | grep -c '^Commits: ')" 463# A phrase: only the subject and the body that have it as written, ignoring64# case, and it is marked whole.65ok match "$ix" '"fix the search"'66eq "$(output | grep '^Commits: ' | sed 's/ | .*//')" 'Commits: [Fix the search] box67Commits: Tidy the box'68has "$T_LOG" '^Commits: Tidy the box \| This is to \[fix the search\] for good\.$'69# A run of whitespace in a phrase matches any run, both ways: spaced out,70# it finds single spaces, and single spaces find a spaced-out subject,71# marked whole.72ok match "$ix" '"fix the search"'73eq "$(output | grep '^Commits: ' | sed 's/ | .*//')" 'Commits: [Fix the search] box74Commits: Tidy the box'75ok match "$ix" '"align the columns"'76eq "$(output | sed 's/ | .*//')" 'Commits: [Align the columns]'77ok match "$ix" '"align the columns"'78eq "$(output | sed 's/ | .*//')" 'Commits: [Align the columns]'79ok match "$ix" '"align thecolumns"'80eq "$(output)" ''81# Unclosed, it is the same phrase.82ok match "$ix" '"FIX THE SEARCH'83eq "$(output | grep '^Commits: ' | sed 's/ | .*//')" 'Commits: [Fix the search] box84Commits: Tidy the box'85# Mixed: the phrase and the word must both match.86ok match "$ix" '"search box" fix'87eq "$(output)" "$(match "$ix" 'fix "search box"')"88eq "$(output | sed 's/ | .*//')" 'Commits: [Fix] the [search box]'89# Reviews too (and the review's commit, which the index has as well).90ok match "$ix" '"search box"'91eq "$(output | sed 's/ | .*//')" 'Reviews: #1 Make the [search box] wider92Commits: Make the [search box] wider93Commits: Fix the [search box]'94# Nothing to look for: empty quotes match nothing, as an empty query does.95ok match "$ix" '""'96eq "$(output)" ''97ok match "$ix" '"box search fix"'98eq "$(output | sed 's/ | .*//')" 'Commits: [box search fix]'99ok match "$ix" '"fix the box"'100eq "$(output)" ''101102# Repos on the index page: names and descriptions, the same way.103ok match "$FORGE_WWW/repos.json" 'hello world'104eq "$(output)" 'Repositories: dami/greet | say [hello] [world]105Repositories: dami/other | [hello] there, [world]'106ok match "$FORGE_WWW/repos.json" '"hello world"'107eq "$(output)" 'Repositories: dami/greet | say [hello world]'108109# Code search finds lines the same way, both ways, tabs too: the index110# looks up each piece of 3 characters or more, near the others, and the111# line check takes any run of whitespace for a space. A phrase without such112# a piece is looked up as written, so it finds single-spaced lines only.113db=$FORGE_WWW/dami/greet/code.db114code() { node "$T_HOME/test/code-search-bench.ts" sql "$db" "$1"; }115ok code '"width = height"'116eq "$(output)" 'sizes.txt:1: width = height'117ok code '"depth = length"'118eq "$(output)" 'sizes.txt:2: depth = length'119ok code '"total count"'120eq "$(output)" "$(printf 'sizes.txt:3: total\tcount')"121ok code '"WIDTH = height" "depth"'122eq "$(output)" ''123ok code '"x = 1"'124eq "$(output)" 'sizes.txt:4: x = 1'125ok code '"y = 2"'126eq "$(output)" ''127128# Pages load search.js as a module, which imports query.js by its shipped name.129has "$FORGE_WWW/dami/greet/index.html" '<script type="module" src="/assets/search\.[0-9A-Za-z_-]{10}\.js"></script>'130has "$FORGE_WWW/index.html" '<script type="module" src="/assets/search\.[0-9A-Za-z_-]{10}\.js"></script>'131s=$(ls "$FORGE_WWW"/assets/search.*.js)132has "$s" "^import \{ [a-zA-Z, ]+ \} from '\./query\.[0-9A-Za-z_-]{10}\.js';$"133exists "$FORGE_WWW/assets/$(sed -n "s|^import .* from '\./\(query\.[^']*\)';\$|\1|p" "$s")"