Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Add a script to test the parser against the Crystal stdlib.
Browse files Browse the repository at this point in the history
There's a file with a list of files that are expected to fail, if they
doesn't match the test will fail.

Bad news, current grammar has only 0.01% of success on compiler stdlib.
  • Loading branch information
hugopl committed Nov 29, 2024
1 parent a072c04 commit 6905ec1
Show file tree
Hide file tree
Showing 5 changed files with 1,483 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
crystal: latest

- run: npm install
- run: npm test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
build/
node_modules/

test/real_world/stdlib_failed.txt
package-lock.json
tree-sitter-crystal.wasm
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"format": "prettier --write ./grammar.js",
"lint": "eslint grammar.js",
"generate": "tree-sitter generate",
"test": "tree-sitter test",
"test": "tree-sitter test;test/real_world/stdlib",
"install": "node-gyp-build",
"prebuildify": "prebuildify --napi --strip"
},
Expand Down
69 changes: 69 additions & 0 deletions test/real_world/stdlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/env crystal
require "colorize"

PASS = "pass".colorize.green
FAIL = "fail".colorize.red

class Test
getter file_path : String
getter label : String
getter elapsed : Time::Span = Time::Span::ZERO

def initialize(@file_path, @label)
end

def execute : Bool
process = Process.new("tree-sitter parse #{@file_path}", shell: true)
start_time = Time.monotonic
status = process.wait
@elapsed = Time.monotonic - start_time
status.success?
end
end

def info(key, value)
puts "#{key}: #{value.colorize.blue}"
end

def find_stdlib_files
# Find stdlib path and version
stdlib_path = Crystal::PATH.split(":").find do |path|
File.exists?(Path[path, "array.cr"])
end
abort("Stdlib path not found.") if stdlib_path.nil?

stdlib_version = File.read(Path[stdlib_path, "VERSION"]).strip

info("stdlib version", stdlib_version)
info("stdlib path", stdlib_path)

# Grab all stdlib files
{stdlib_path, Dir["#{stdlib_path}/**/*.cr"].sort!}
end

stdlib_path, stdlib_files = find_stdlib_files
pass = 0

expected_fail = File.read("#{__DIR__}/stdlib_expected_to_fail.txt").split
failed = [] of String

stdlib_files.each do |stdlib_file|
test = Test.new(stdlib_file, stdlib_file[(stdlib_path.size + 1)..])
success = test.execute

if success
pass += 1
else
failed << test.label
end
elapsed_ms = "#{test.elapsed.total_milliseconds}ms".colorize.dark_gray
# Why 63? So we match 80 columns.
printf("%-63s %s %s\n", test.label, success ? PASS : FAIL, elapsed_ms)
end

printf("%% of success: %.2f%%\n", pass / stdlib_files.size)

File.write("#{__DIR__}/stdlib_failed.txt", failed.join("\n"))
if failed != expected_fail
abort("List of failed tests difer, check stdlib_failed.txt and stdlib_expected_to_fail.txt".colorize.red)
end
Loading

0 comments on commit 6905ec1

Please sign in to comment.