-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
I hate tests that touch the filesystem, but in this case I think it's necessary. I can't know which import files to read without loading them, so I can't set up an in-memory system very easily. Maybe if there was a mock simplifiles? 🤔
- Loading branch information
1 parent
4dfffa5
commit b85dad6
Showing
4 changed files
with
155 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import compiler | ||
import compiler/program | ||
import filepath | ||
import gleam/dict | ||
import gleam/list | ||
import gleam/option | ||
import gleam/set | ||
import gleam/string | ||
import gleeunit/should | ||
import macabre | ||
import simplifile | ||
import temporary | ||
|
||
// These tests have to touch the filesystem, so | ||
// they add measurably to the compile time. | ||
// Tests in other files are pure and require no IO. | ||
// This file should *only* test that stuff is being placed | ||
// in the right directories. | ||
// | ||
// I tried to bulk all the situations in just one test, but | ||
// it may have to be split out if it becomes too hard to | ||
// maintain. | ||
|
||
pub type ProjectFiles { | ||
ProjectFiles( | ||
base_dir: String, | ||
src_dir: String, | ||
build_dir: String, | ||
main_path: String, | ||
) | ||
} | ||
|
||
fn init_folders( | ||
use_function: fn(ProjectFiles) -> a, | ||
) -> Result(a, simplifile.FileError) { | ||
use dir <- temporary.create(temporary.directory()) | ||
let project_name = filepath.base_name(dir) | ||
let src = filepath.join(dir, "src") | ||
let build = filepath.join(dir, "build") | ||
let main_path = filepath.join(src, project_name <> ".gleam") | ||
|
||
simplifile.create_directory_all(src) | ||
|> should.be_ok | ||
let project_files = | ||
ProjectFiles( | ||
base_dir: dir, | ||
src_dir: src, | ||
build_dir: build, | ||
main_path: main_path, | ||
) | ||
use_function(project_files) | ||
} | ||
|
||
pub fn program_compile_test_with_nested_folders_test() { | ||
// src/<dirname.gleam> | ||
// src/baz.py | ||
// src/foo/bar.gleam | ||
// src/foo/bindings.py | ||
use project_files <- init_folders() | ||
simplifile.write( | ||
to: project_files.main_path, | ||
contents: "import foo/bar | ||
@external(python, \"baz\", \"baz\") | ||
fn baz() -> Nil | ||
pub fn main() {}", | ||
) | ||
|> should.be_ok | ||
|
||
simplifile.write( | ||
to: filepath.join(project_files.src_dir, "baz.py"), | ||
contents: " | ||
fn baz(): | ||
print('baz')", | ||
) | ||
|> should.be_ok | ||
|
||
let foo_dir = filepath.join(project_files.src_dir, "foo") | ||
simplifile.create_directory_all(foo_dir) | ||
|> should.be_ok | ||
simplifile.write( | ||
to: filepath.join(foo_dir, "bar.gleam"), | ||
contents: "@external(python, \"foo.bindings\", \"bar\") | ||
fn bar() -> Nil", | ||
) | ||
|> should.be_ok | ||
|
||
simplifile.write( | ||
to: filepath.join(foo_dir, "bindings.py"), | ||
contents: "def bar(): | ||
pass", | ||
) | ||
|> should.be_ok | ||
|
||
let gleam_program = | ||
program.load_program(project_files.base_dir) | ||
|> should.be_ok | ||
|
||
// load | ||
|
||
should.equal(gleam_program.base_directory, project_files.base_dir) | ||
should.equal( | ||
gleam_program.main_module, | ||
filepath.base_name(project_files.main_path), | ||
) | ||
gleam_program.modules | ||
|> dict.size | ||
|> should.equal(2) | ||
gleam_program.external_import_files |> set.size |> should.equal(2) | ||
|
||
// --- compile | ||
let compiled_program = compiler.compile_program(gleam_program) | ||
should.equal(compiled_program.base_directory, project_files.base_dir) | ||
should.equal( | ||
compiled_program.main_module, | ||
option.Some( | ||
filepath.base_name(project_files.main_path) |> string.drop_right(6), | ||
), | ||
) | ||
compiled_program.modules | ||
|> dict.size | ||
|> should.equal(2) | ||
compiled_program.external_import_files |> set.size |> should.equal(2) | ||
|
||
// --- write output | ||
macabre.write_program(compiled_program) |> should.be_ok | ||
|
||
simplifile.read_directory(project_files.build_dir) | ||
|> should.be_ok | ||
|> list.sort(string.compare) | ||
|> should.equal([ | ||
filepath.base_name(project_files.main_path) |> string.drop_right(6) <> ".py", | ||
"__main__.py", | ||
"baz.py", | ||
"foo", | ||
"gleam_builtins.py", | ||
]) | ||
|
||
project_files.build_dir | ||
|> filepath.join("foo") | ||
|> simplifile.read_directory | ||
|> should.be_ok | ||
|> should.equal(["bindings.py", "bar.py"]) | ||
} |