github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/logfilters.test.ts (about)

     1  import { Location } from "history"
     2  import {
     3    EMPTY_FILTER_TERM,
     4    filterSetFromLocation,
     5    parseTermInput,
     6    TermState,
     7  } from "./logfilters"
     8  
     9  enum TestStrings {
    10    Basic = "abc",
    11    BuildCommand = 'Step 1 - 0.00s (Running command: [sh -c services="red" ./generate-start.sh] (in "/Users/lizz/Documents/Repos/pixeltilt/full"))',
    12    BuildError404 = "Build Failed: ImageBuild: failed to compute cache key: failed to walk /var/lib/docker/tmp/buildkit-mount767282166/red: lstat /var/lib/docker/tmp/buildkit-mount767282166/red: no such file or directory",
    13    BuildErrorInFile = "ERROR IN: [5/5] ADD storage/main ./",
    14    BuildInfoLine = "[1/5] FROM docker.io/library/alpine@sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f",
    15    SyntaxError = "→ render/start.go:9:33: syntax error: unexpected N, expecting comma or )",
    16  }
    17  
    18  describe("Log filters", () => {
    19    describe("state generation", () => {
    20      describe("for term filter", () => {
    21        it("gets set with an empty state if no term is present", () => {
    22          const emptyTermLocation = { search: "term=" } as Location
    23          expect(filterSetFromLocation(emptyTermLocation).term).toEqual(
    24            EMPTY_FILTER_TERM
    25          )
    26  
    27          const noTermLocation = { search: "" } as Location
    28          expect(filterSetFromLocation(noTermLocation).term).toEqual(
    29            EMPTY_FILTER_TERM
    30          )
    31        })
    32  
    33        it("gets set with a parsed state if a valid term is present", () => {
    34          const textLocation = { search: "term=docker+build" } as Location
    35          const textParsedTerm = filterSetFromLocation(textLocation).term
    36          expect(textParsedTerm.state).toEqual(TermState.Parsed)
    37          expect(textParsedTerm.input).toEqual("docker build")
    38          expect(textParsedTerm.hasOwnProperty("regexp")).toBe(true)
    39          expect(textParsedTerm.hasOwnProperty("error")).toBe(false)
    40  
    41          const regexpLocation = { search: "term=%2Fdocker%2F" } as Location
    42          const regexpParsedTerm = filterSetFromLocation(regexpLocation).term
    43          expect(regexpParsedTerm.state).toEqual(TermState.Parsed)
    44          expect(regexpParsedTerm.input).toEqual("/docker/")
    45          expect(regexpParsedTerm.hasOwnProperty("regexp")).toBe(true)
    46          expect(regexpParsedTerm.hasOwnProperty("error")).toBe(false)
    47        })
    48  
    49        it("gets set with an error state if an invalid input is present", () => {
    50          const location = { search: "term=%2Fdock(er%3F%2F" } as Location
    51          const parsedTerm = filterSetFromLocation(location).term
    52          expect(parsedTerm.state).toEqual(TermState.Error)
    53          expect(parsedTerm.input).toEqual("/dock(er?/")
    54          expect(parsedTerm.hasOwnProperty("regexp")).toBe(false)
    55          expect(parsedTerm.hasOwnProperty("error")).toBe(true)
    56        })
    57      })
    58  
    59      describe("term parsing", () => {
    60        describe("for string literals", () => {
    61          it("matches on the expected text", () => {
    62            expect(parseTermInput("abc").test(TestStrings.Basic)).toBe(true)
    63            expect(parseTermInput("SERVICE").test(TestStrings.BuildCommand)).toBe(
    64              true
    65            )
    66            expect(
    67              parseTermInput("random phrase").test(TestStrings.BuildInfoLine)
    68            ).toBe(false)
    69            expect(parseTermInput("ab5d63").test(TestStrings.BuildInfoLine)).toBe(
    70              true
    71            )
    72            expect(parseTermInput("error").test(TestStrings.SyntaxError)).toBe(
    73              true
    74            )
    75            expect(parseTermInput("mount").test(TestStrings.BuildError404)).toBe(
    76              true
    77            )
    78            expect(parseTermInput("mount ").test(TestStrings.BuildError404)).toBe(
    79              false
    80            )
    81          })
    82  
    83          it("is not stateful", () => {
    84            let parsed = parseTermInput("line 1")
    85            expect(parsed.test("line 123")).toBe(true)
    86            expect(parsed.test("line 124")).toBe(true)
    87            expect(parsed.test("line 125")).toBe(true)
    88            expect(parsed.test("line 126")).toBe(true)
    89          })
    90  
    91          it("escapes any RegExp-specific characters", () => {
    92            expect(parseTermInput("ab?c").test(TestStrings.Basic)).toBe(false)
    93            expect(parseTermInput('"red"').test(TestStrings.BuildCommand)).toBe(
    94              true
    95            )
    96            expect(
    97              parseTermInput("generate-start.sh").test(TestStrings.BuildCommand)
    98            ).toBe(true)
    99            expect(parseTermInput("w").test(TestStrings.BuildInfoLine)).toBe(
   100              false
   101            )
   102            expect(
   103              parseTermInput("comma or )").test(TestStrings.SyntaxError)
   104            ).toBe(true)
   105            expect(
   106              parseTermInput("ERROR.+").test(TestStrings.BuildErrorInFile)
   107            ).toBe(false)
   108            expect(parseTermInput("[1/5]").test(TestStrings.BuildInfoLine)).toBe(
   109              true
   110            )
   111          })
   112        })
   113  
   114        describe("for regular expressions", () => {
   115          it("only parses strings surrounded by forward slashes as regexp", () => {
   116            expect(
   117              parseTermInput("/docker/").test(TestStrings.BuildInfoLine)
   118            ).toBe(true)
   119            expect(
   120              parseTermInput("/docker").test(TestStrings.BuildInfoLine)
   121            ).toBe(false)
   122          })
   123  
   124          it("matches on the expected text", () => {
   125            expect(parseTermInput("/ab?c/").test(TestStrings.Basic)).toBe(true)
   126            expect(
   127              parseTermInput("/error.+main/").test(TestStrings.BuildErrorInFile)
   128            ).toBe(true)
   129            expect(parseTermInput("/d+/").test(TestStrings.Basic)).toBe(false)
   130            expect(parseTermInput("/d+/").test(TestStrings.BuildInfoLine)).toBe(
   131              true
   132            )
   133            expect(
   134              parseTermInput("/failed:/").test(TestStrings.BuildError404)
   135            ).toBe(true)
   136          })
   137  
   138          it("throws an error when input text is invalid regex", () => {
   139            expect(() =>
   140              parseTermInput("/(missing)? parenthesis)/")
   141            ).toThrowError(/Invalid regular expression/)
   142          })
   143        })
   144      })
   145    })
   146  })