Skip to content

Commit 18a4b2f

Browse files
authored
test untested path funs (#373)
* test untested path funs * cleanup + expect test * better error messages * print cwd, fix print order * check ripgrep installed * install ripgrep * fix binary name * more robust regex
1 parent 7181255 commit 18a4b2f

File tree

10 files changed

+625
-40
lines changed

10 files changed

+625
-40
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ jobs:
4545

4646
- run: |
4747
sudo apt update
48-
sudo apt install -y expect ncat valgrind
48+
sudo apt install -y expect ncat valgrind ripgrep
4949
# expect for testing
5050
# ncat for tcp-client example
51+
# ripgrep for ci/check_all_exposed_funs_tested.roc
5152

5253
- run: expect -v
5354

ci/all_tests.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ for roc_file in $TESTS_DIR*.roc; do
3838
$ROC check $roc_file
3939
done
4040

41+
$ROC ci/check_all_exposed_funs_tested.roc
42+
4143
# roc build
4244
architecture=$(uname -m)
4345

@@ -60,6 +62,15 @@ cd ci/rust_http_server
6062
cargo build --release
6163
cd ../..
6264

65+
# Check for duplicate .roc file names between EXAMPLES_DIR and TESTS_DIR (this messes with checks)
66+
for example_file in $EXAMPLES_DIR*.roc; do
67+
example_basename=$(basename "$example_file")
68+
if [ -f "$TESTS_DIR$example_basename" ]; then
69+
echo "ERROR: Duplicate file name found: $example_basename exists in both $EXAMPLES_DIR and $TESTS_DIR. Change the name of one of them." >&2
70+
exit 1
71+
fi
72+
done
73+
6374
# check output with linux expect
6475
for roc_file in $EXAMPLES_DIR*.roc; do
6576
base_file=$(basename "$roc_file")

ci/check_all_exposed_funs_tested.roc

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }
1+
app [main!] { pf: platform "../platform/main.roc" }
22

33
import pf.Stdout
44
import pf.Arg exposing [Arg]
55
import pf.File
66
import pf.Cmd
7+
import pf.Env
8+
import pf.Path
9+
import pf.Sleep
710

811
# This script performs the following tasks:
912
# 1. Reads the file platform/main.roc and extracts the exposes list.
@@ -16,6 +19,9 @@ err_s = |err_msg| Err(StrErr(err_msg))
1619

1720
main! : List Arg => Result {} _
1821
main! = |_args|
22+
cwd = Env.cwd!({}) ? |err| FailedToGetCwd(err)
23+
Stdout.line!("Current working directory: ${Path.display(cwd)}")?
24+
1925
path_to_platform_main = "platform/main.roc"
2026

2127
main_content =
@@ -67,34 +73,74 @@ main! = |_args|
6773
|function_name|
6874
Stdout.line!(function_name),
6975
)?
76+
77+
# Sleep to fix print order
78+
Sleep.millis!(1000)
7079
Err(Exit(1, "I found untested functions, see above."))
7180
7281
is_function_unused! : Str, Str => Result Bool _
7382
is_function_unused! = |module_name, function_name|
7483
function_pattern = "${module_name}.${function_name}"
7584
search_dirs = ["examples", "tests"]
7685
77-
unused_in_dir =
78-
search_dirs
79-
|> List.map_try!( |search_dir|
80-
# Use ripgrep to search for the function pattern
81-
cmd =
82-
Cmd.new("rg")
83-
|> Cmd.arg("-q") # Quiet mode - we only care about exit code
84-
|> Cmd.arg(function_pattern)
85-
|> Cmd.arg(search_dir)
86-
87-
status_res = Cmd.status!(cmd)
88-
89-
# ripgrep returns status 0 if matches were found, 1 if no matches
90-
when status_res is
91-
Ok(0) -> Ok(Bool.false) # Function is used (not unused)
92-
_ -> Ok(Bool.true)
93-
)?
86+
# Check current working directory
87+
cwd = Env.cwd!({}) ? |err| FailedToGetCwd2(err)
88+
89+
# Check if directories exist
90+
List.for_each_try!(
91+
search_dirs,
92+
|search_dir|
93+
is_dir_res = File.is_dir!(search_dir)
94+
95+
when is_dir_res is
96+
Ok is_dir ->
97+
if !is_dir then
98+
err_s("Error: Path '${search_dir}' inside ${Path.display(cwd)} is not a directory.")
99+
else
100+
Ok({})
101+
102+
Err (PathErr NotFound) ->
103+
err_s("Error: Directory '${search_dir}' does not exist in ${Path.display(cwd)}")
104+
Err err ->
105+
err_s("Error checking directory '${search_dir}': ${Inspect.to_str(err)}")
106+
)?
107+
108+
# Check if ripgrep is installed
109+
rg_check_cmd = Cmd.new("rg") |> Cmd.arg("--version")
110+
rg_check_output = Cmd.output!(rg_check_cmd)
111+
112+
when rg_check_output.status is
113+
Ok(0) ->
114+
unused_in_dir =
115+
search_dirs
116+
|> List.map_try!( |search_dir|
117+
# Skip searching if directory doesn't exist
118+
dir_exists = File.is_dir!(search_dir)?
119+
if !dir_exists then
120+
Ok(Bool.true) # Consider unused if we can't search
121+
else
122+
# Use ripgrep to search for the function pattern
123+
cmd =
124+
Cmd.new("rg")
125+
|> Cmd.arg("-q") # Quiet mode - we only care about exit code
126+
|> Cmd.arg(function_pattern)
127+
|> Cmd.arg(search_dir)
128+
129+
status_res = Cmd.status!(cmd)
130+
131+
# ripgrep returns status 0 if matches were found, 1 if no matches
132+
when status_res is
133+
Ok(0) -> Ok(Bool.false) # Function is used (not unused)
134+
_ -> Ok(Bool.true)
135+
)?
136+
137+
unused_in_dir
138+
|> List.walk!(Bool.true, |state, is_unused_res| state && is_unused_res)
139+
|> Ok
140+
_ ->
141+
err_s("Error: ripgrep (rg) is not installed or not available in PATH. Please install ripgrep to use this script. Full output: ${Inspect.to_str(rg_check_output)}")
142+
94143

95-
unused_in_dir
96-
|> List.walk!(Bool.true, |state, is_unused_res| state && is_unused_res)
97-
|> Ok
98144

99145
process_module! : Str => Result { module_name : Str, exposed_functions : List Str } _
100146
process_module! = |module_name|

ci/expect_scripts/file.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ expect "Testing some File functions..." {
5858
expect "✓ Deleted all files." {
5959

6060
# Final completion message
61-
expect "✓ All File function tests completed! ✓" {
61+
expect "I ran all file function tests." {
6262
expect eof {
6363
check_exit_and_segfault
6464
}

0 commit comments

Comments
 (0)