项目文件夹

文件
wehub-resource-sync 95f0813436
build / build (push) Failing after 0s
build / snapshot (push) Failing after 0s
lint / lint (push) Failing after 1s
nightly / nightly (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 13:02:37 +08:00

387 行
9.6 KiB
Go

package lexer
import (
"os"
"testing"
"github.com/charmbracelet/vhs/token"
)
func TestNextToken(t *testing.T) {
input := `
Output examples/out.gif
Set FontSize 42
Set Padding 5
Set CursorBlink false
Type "echo 'Hello, world!'"
Enter
Type@.1 "echo 'Hello, world!'"
Left 3
Sleep 1
Right@100ms 3
ScrollUp 3
ScrollDown@100ms 2
Sleep 500ms
Ctrl+C
Enter
Ctrl+@
Ctrl+\
Alt+]
Shift+[
Sleep .1
Sleep 100ms
Sleep 2
Wait+Screen@1m /foobar/
Wait+Screen@1m /foo\/bar/
Wait+Screen@1m /foo\\/
Wait+Screen@1m /foo\\\/bar/`
tests := []struct {
expectedType token.Type
expectedLiteral string
}{
{token.OUTPUT, "Output"},
{token.STRING, "examples/out.gif"},
{token.SET, "Set"},
{token.FONT_SIZE, "FontSize"},
{token.NUMBER, "42"},
{token.SET, "Set"},
{token.PADDING, "Padding"},
{token.NUMBER, "5"},
{token.SET, "Set"},
{token.CURSOR_BLINK, "CursorBlink"},
{token.BOOLEAN, "false"},
{token.TYPE, "Type"},
{token.STRING, "echo 'Hello, world!'"},
{token.ENTER, "Enter"},
{token.TYPE, "Type"},
{token.AT, "@"},
{token.NUMBER, ".1"},
{token.STRING, "echo 'Hello, world!'"},
{token.LEFT, "Left"},
{token.NUMBER, "3"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "1"},
{token.RIGHT, "Right"},
{token.AT, "@"},
{token.NUMBER, "100"},
{token.MILLISECONDS, "ms"},
{token.NUMBER, "3"},
{token.SCROLL_UP, "ScrollUp"},
{token.NUMBER, "3"},
{token.SCROLL_DOWN, "ScrollDown"},
{token.AT, "@"},
{token.NUMBER, "100"},
{token.MILLISECONDS, "ms"},
{token.NUMBER, "2"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "500"},
{token.MILLISECONDS, "ms"},
{token.CTRL, "Ctrl"},
{token.PLUS, "+"},
{token.STRING, "C"},
{token.ENTER, "Enter"},
{token.CTRL, "Ctrl"},
{token.PLUS, "+"},
{token.AT, "@"},
{token.CTRL, "Ctrl"},
{token.PLUS, "+"},
{token.BACKSLASH, "\\"},
{token.ALT, "Alt"},
{token.PLUS, "+"},
{token.RIGHT_BRACKET, "]"},
{token.SHIFT, "Shift"},
{token.PLUS, "+"},
{token.LEFT_BRACKET, "["},
{token.SLEEP, "Sleep"},
{token.NUMBER, ".1"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "100"},
{token.MILLISECONDS, "ms"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "2"},
{token.WAIT, "Wait"},
{token.PLUS, "+"},
{token.STRING, "Screen"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.MINUTES, "m"},
{token.REGEX, "foobar"},
{token.WAIT, "Wait"},
{token.PLUS, "+"},
{token.STRING, "Screen"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.MINUTES, "m"},
{token.REGEX, "foo\\/bar"},
{token.WAIT, "Wait"},
{token.PLUS, "+"},
{token.STRING, "Screen"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.MINUTES, "m"},
{token.REGEX, "foo\\\\"},
{token.WAIT, "Wait"},
{token.PLUS, "+"},
{token.STRING, "Screen"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.MINUTES, "m"},
{token.REGEX, "foo\\\\\\/bar"},
}
l := New(input)
for i, tt := range tests {
tok := l.NextToken()
if tok.Type != tt.expectedType {
t.Fatalf("tests[%d] - tokentype wrong. expected=%q, got=%q", i, tt.expectedType, tok.Type)
}
if tok.Literal != tt.expectedLiteral {
t.Fatalf("tests[%d] - literal wrong. expected=%q, got=%q", i, tt.expectedLiteral, tok.Literal)
}
}
}
func TestLexTapeFile(t *testing.T) {
input, err := os.ReadFile("../examples/fixtures/all.tape")
if err != nil {
t.Fatal("could not read all.tape file")
}
tests := []struct {
expectedType token.Type
expectedLiteral string
}{
{token.COMMENT, " All Commands"},
{token.COMMENT, " Output:"},
{token.OUTPUT, "Output"},
{token.STRING, "examples/fixtures/all.gif"},
{token.OUTPUT, "Output"},
{token.STRING, "examples/fixtures/all.mp4"},
{token.OUTPUT, "Output"},
{token.STRING, "examples/fixtures/all.webm"},
{token.COMMENT, " Settings:"},
{token.SET, "Set"},
{token.SHELL, "Shell"},
{token.STRING, "fish"},
{token.SET, "Set"},
{token.FONT_SIZE, "FontSize"},
{token.NUMBER, "22"},
{token.SET, "Set"},
{token.FONT_FAMILY, "FontFamily"},
{token.STRING, "DejaVu Sans Mono"},
{token.SET, "Set"},
{token.HEIGHT, "Height"},
{token.NUMBER, "600"},
{token.SET, "Set"},
{token.WIDTH, "Width"},
{token.NUMBER, "1200"},
{token.SET, "Set"},
{token.LETTER_SPACING, "LetterSpacing"},
{token.NUMBER, "1"},
{token.SET, "Set"},
{token.LINE_HEIGHT, "LineHeight"},
{token.NUMBER, "1.2"},
{token.SET, "Set"},
{token.THEME, "Theme"},
{token.JSON, "{ \"name\": \"Whimsy\", \"black\": \"#535178\", \"red\": \"#ef6487\", \"green\": \"#5eca89\", \"yellow\": \"#fdd877\", \"blue\": \"#65aef7\", \"purple\": \"#aa7ff0\", \"cyan\": \"#43c1be\", \"white\": \"#ffffff\", \"brightBlack\": \"#535178\", \"brightRed\": \"#ef6487\", \"brightGreen\": \"#5eca89\", \"brightYellow\": \"#fdd877\", \"brightBlue\": \"#65aef7\", \"brightPurple\": \"#aa7ff0\", \"brightCyan\": \"#43c1be\", \"brightWhite\": \"#ffffff\", \"background\": \"#29283b\", \"foreground\": \"#b3b0d6\", \"selectionBackground\": \"#3d3c58\", \"cursorColor\": \"#b3b0d6\" }"},
{token.SET, "Set"},
{token.THEME, "Theme"},
{token.STRING, "Catppuccin Mocha"},
{token.SET, "Set"},
{token.PADDING, "Padding"},
{token.NUMBER, "50"},
{token.SET, "Set"},
{token.FRAMERATE, "Framerate"},
{token.NUMBER, "60"},
{token.SET, "Set"},
{token.PLAYBACK_SPEED, "PlaybackSpeed"},
{token.NUMBER, "2"},
{token.SET, "Set"},
{token.TYPING_SPEED, "TypingSpeed"},
{token.NUMBER, ".1"},
{token.SET, "Set"},
{token.LOOP_OFFSET, "LoopOffset"},
{token.NUMBER, "60.4"},
{token.SET, "Set"},
{token.LOOP_OFFSET, "LoopOffset"},
{token.NUMBER, "20.99"},
{token.PERCENT, "%"},
{token.SET, "Set"},
{token.CURSOR_BLINK, "CursorBlink"},
{token.BOOLEAN, "false"},
{token.COMMENT, " Sleep:"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "1"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "500"},
{token.MILLISECONDS, "ms"},
{token.SLEEP, "Sleep"},
{token.NUMBER, ".5"},
{token.SLEEP, "Sleep"},
{token.NUMBER, "0.5"},
{token.COMMENT, " Type:"},
{token.TYPE, "Type"},
{token.AT, "@"},
{token.NUMBER, ".5"},
{token.STRING, "All"},
{token.TYPE, "Type"},
{token.AT, "@"},
{token.NUMBER, "500"},
{token.MILLISECONDS, "ms"},
{token.STRING, "All"},
{token.TYPE, "Type"},
{token.STRING, "Double Quote"},
{token.TYPE, "Type"},
{token.STRING, "\"Single\" Quote"},
{token.TYPE, "Type"},
{token.STRING, `"Backtick" 'Quote'`},
{token.COMMENT, " Keys:"},
{token.BACKSPACE, "Backspace"},
{token.BACKSPACE, "Backspace"},
{token.NUMBER, "2"},
{token.BACKSPACE, "Backspace"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.DELETE, "Delete"},
{token.DELETE, "Delete"},
{token.NUMBER, "2"},
{token.DELETE, "Delete"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.INSERT, "Insert"},
{token.INSERT, "Insert"},
{token.NUMBER, "2"},
{token.INSERT, "Insert"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.DOWN, "Down"},
{token.DOWN, "Down"},
{token.NUMBER, "2"},
{token.DOWN, "Down"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.PAGE_DOWN, "PageDown"},
{token.PAGE_DOWN, "PageDown"},
{token.NUMBER, "2"},
{token.PAGE_DOWN, "PageDown"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.SCROLL_DOWN, "ScrollDown"},
{token.SCROLL_DOWN, "ScrollDown"},
{token.NUMBER, "2"},
{token.SCROLL_DOWN, "ScrollDown"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.ENTER, "Enter"},
{token.ENTER, "Enter"},
{token.NUMBER, "2"},
{token.ENTER, "Enter"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.SPACE, "Space"},
{token.SPACE, "Space"},
{token.NUMBER, "2"},
{token.SPACE, "Space"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.TAB, "Tab"},
{token.TAB, "Tab"},
{token.NUMBER, "2"},
{token.TAB, "Tab"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.LEFT, "Left"},
{token.LEFT, "Left"},
{token.NUMBER, "2"},
{token.LEFT, "Left"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.RIGHT, "Right"},
{token.RIGHT, "Right"},
{token.NUMBER, "2"},
{token.RIGHT, "Right"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.UP, "Up"},
{token.UP, "Up"},
{token.NUMBER, "2"},
{token.UP, "Up"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.PAGE_UP, "PageUp"},
{token.PAGE_UP, "PageUp"},
{token.NUMBER, "2"},
{token.PAGE_UP, "PageUp"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.SCROLL_UP, "ScrollUp"},
{token.SCROLL_UP, "ScrollUp"},
{token.NUMBER, "2"},
{token.SCROLL_UP, "ScrollUp"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.DOWN, "Down"},
{token.DOWN, "Down"},
{token.NUMBER, "2"},
{token.DOWN, "Down"},
{token.AT, "@"},
{token.NUMBER, "1"},
{token.NUMBER, "3"},
{token.COMMENT, " Control:"},
{token.CTRL, "Ctrl"},
{token.PLUS, "+"},
{token.STRING, "C"},
{token.CTRL, "Ctrl"},
{token.PLUS, "+"},
{token.STRING, "L"},
{token.CTRL, "Ctrl"},
{token.PLUS, "+"},
{token.STRING, "R"},
{token.COMMENT, " Alt:"},
{token.ALT, "Alt"},
{token.PLUS, "+"},
{token.STRING, "."},
{token.ALT, "Alt"},
{token.PLUS, "+"},
{token.STRING, "L"},
{token.ALT, "Alt"},
{token.PLUS, "+"},
{token.STRING, "i"},
{token.COMMENT, " Display:"},
{token.HIDE, "Hide"},
{token.SHOW, "Show"},
}
l := New(string(input))
for i, tt := range tests {
tok := l.NextToken()
if tok.Type != tt.expectedType {
t.Fatalf("tests[%d] - tokentype wrong. expected=%q, got=%q", i, tt.expectedType, tok.Type)
}
if tok.Literal != tt.expectedLiteral {
t.Fatalf("tests[%d] - literal wrong. expected=%q, got=%q", i, tt.expectedLiteral, tok.Literal)
}
}
}