Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
21 changes: 1 addition & 20 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,11 @@
To find the next explain test to work on (fewest pending statements first), run:

```bash
go run ./cmd/next-test -explain
go run ./cmd/next-test
```

This finds tests with `explain_todo` entries in their metadata.

To find the next format roundtrip test to work on, run:

```bash
go run ./cmd/next-test -format
```

This finds tests with `todo_format: true` in their metadata.

## Running Tests

Always run parser tests with a 5 second timeout:
Expand All @@ -28,16 +20,6 @@ go test ./parser/... -timeout 5s

The tests are very fast. If a test is timing out, it indicates a bug (likely an infinite loop in the parser).

## Checking for Newly Passing Format Tests

After implementing format changes, run:

```bash
go test ./parser/... -check-format -v 2>&1 | grep "FORMAT PASSES NOW"
```

Tests that output `FORMAT PASSES NOW` can have their `todo_format` flag removed from `metadata.json`.

## Checking for Newly Passing Explain Tests

After implementing parser/explain changes, run:
Expand All @@ -59,7 +41,6 @@ Each test in `parser/testdata/` contains:

### Metadata Options

- `todo_format: true` - Format roundtrip test is pending implementation
- `explain_todo: {"stmt2": true}` - Skip specific statement subtests
- `skip: true` - Skip test entirely (e.g., causes infinite loop)
- `explain: false` - Skip test (e.g., ClickHouse couldn't parse it)
Expand Down
81 changes: 21 additions & 60 deletions cmd/next-test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ package main

import (
"encoding/json"
"flag"
"fmt"
"os"
"path/filepath"
"sort"
)

var formatFlag = flag.Bool("format", false, "Find tests with todo_format: true")
var explainFlag = flag.Bool("explain", false, "Find tests with explain_todo entries (fewest first)")

type testMetadata struct {
TodoFormat bool `json:"todo_format,omitempty"`
ExplainTodo map[string]bool `json:"explain_todo,omitempty"`
Explain *bool `json:"explain,omitempty"`
Skip bool `json:"skip,omitempty"`
Expand All @@ -27,15 +22,6 @@ type todoTest struct {
}

func main() {
flag.Parse()

if !*formatFlag && !*explainFlag {
fmt.Fprintf(os.Stderr, "Usage: go run ./cmd/next-test [-format | -explain]\n")
fmt.Fprintf(os.Stderr, " -format Find tests with todo_format: true\n")
fmt.Fprintf(os.Stderr, " -explain Find tests with explain_todo entries (fewest first)\n")
os.Exit(1)
}

testdataDir := "parser/testdata"
entries, err := os.ReadDir(testdataDir)
if err != nil {
Expand Down Expand Up @@ -69,15 +55,9 @@ func main() {
continue
}

// Check based on flag
if *formatFlag {
if !metadata.TodoFormat {
continue
}
} else if *explainFlag {
if len(metadata.ExplainTodo) == 0 {
continue
}
// Check for explain_todo entries
if len(metadata.ExplainTodo) == 0 {
continue
}

// Read query to get its size
Expand All @@ -94,41 +74,24 @@ func main() {
})
}

todoType := "todo_format"
if *explainFlag {
todoType = "explain_todo"
}

if len(todoTests) == 0 {
fmt.Printf("No %s tests found!\n", todoType)
fmt.Printf("No explain_todo tests found!\n")
return
}

// Sort based on mode
if *explainFlag {
// Sort by explain_todo count (fewest first), then by query size
sort.Slice(todoTests, func(i, j int) bool {
if todoTests[i].explainTodoLen != todoTests[j].explainTodoLen {
return todoTests[i].explainTodoLen < todoTests[j].explainTodoLen
}
return todoTests[i].querySize < todoTests[j].querySize
})
} else {
// Sort by query size (shortest first)
sort.Slice(todoTests, func(i, j int) bool {
return todoTests[i].querySize < todoTests[j].querySize
})
}
// Sort by explain_todo count (fewest first), then by query size
sort.Slice(todoTests, func(i, j int) bool {
if todoTests[i].explainTodoLen != todoTests[j].explainTodoLen {
return todoTests[i].explainTodoLen < todoTests[j].explainTodoLen
}
return todoTests[i].querySize < todoTests[j].querySize
})

// Print the best candidate
next := todoTests[0]
testDir := filepath.Join(testdataDir, next.name)

if *explainFlag {
fmt.Printf("Next %s test: %s (%d pending statements)\n\n", todoType, next.name, next.explainTodoLen)
} else {
fmt.Printf("Next %s test: %s\n\n", todoType, next.name)
}
fmt.Printf("Next explain_todo test: %s (%d pending statements)\n\n", next.name, next.explainTodoLen)

// Print query.sql contents
queryPath := filepath.Join(testDir, "query.sql")
Expand All @@ -141,19 +104,17 @@ func main() {
fmt.Printf("\nExpected EXPLAIN output:\n%s\n", string(explainBytes))
}

// Print explain_todo entries if in explain mode
if *explainFlag {
metadataPath := filepath.Join(testDir, "metadata.json")
if metadataBytes, err := os.ReadFile(metadataPath); err == nil {
var metadata testMetadata
if json.Unmarshal(metadataBytes, &metadata) == nil {
fmt.Printf("\nPending statements (explain_todo):\n")
for stmt := range metadata.ExplainTodo {
fmt.Printf(" - %s\n", stmt)
}
// Print explain_todo entries
metadataPath := filepath.Join(testDir, "metadata.json")
if metadataBytes, err := os.ReadFile(metadataPath); err == nil {
var metadata testMetadata
if json.Unmarshal(metadataBytes, &metadata) == nil {
fmt.Printf("\nPending statements (explain_todo):\n")
for stmt := range metadata.ExplainTodo {
fmt.Printf(" - %s\n", stmt)
}
}
}

fmt.Printf("\nRemaining %s tests: %d\n", todoType, len(todoTests))
fmt.Printf("\nRemaining explain_todo tests: %d\n", len(todoTests))
}
Loading