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

Add a script to test the parser against the Crystal stdlib. #19

Merged
merged 3 commits into from
Nov 29, 2024
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 && crystal run test/real_world/stdlib",
"install": "node-gyp-build",
"prebuildify": "prebuildify --napi --strip"
},
Expand Down
74 changes: 74 additions & 0 deletions test/real_world/stdlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/env crystal

{% skip_file unless flag?(:linux) %}

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)

if failed != expected_fail
abort("List of failed tests difer, check stdlib_failed.txt and stdlib_expected_to_fail.txt".colorize.red)

File.write("#{__DIR__}/stdlib_failed.txt", failed.join("\n"))
system("diff -u #{__DIR__}/stdlib_failed.txt #{__DIR__}/stdlib_failed.txt")
end
Loading