alpha
Login
or
Join now
nandi.uk
/
gleam
Star
2
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Fork of daniellemaywood.uk/gleam — Wasm codegen work
Star
2
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
Metaprogramming test cases
author
Louis Pilfold
date
3 years ago
(Dec 23, 2022, 6:41 PM UTC)
commit
582f85ed
582f85ed01b479d78610612f831b87c4faf493a0
parent
a0bf3117
a0bf3117f03c6ebee0510316f2e3fc700d9f44b2
+193
-8
11 changed files
Expand all
Collapse all
Unified
Split
Cargo.lock
Cargo.toml
compiler-core
src
build
package_compilation_tests.rs
package_compiler.rs
build.rs
io
memory.rs
test-package-compiler
Cargo.toml
build.rs
cases
hello_joe
gleam.toml
src
hello_joe.gleam
src
lib.rs
+11
Cargo.lock
View file
Reviewed
···
1945
1945
]
1946
1946
1947
1947
[[package]]
1948
1948
+
name = "test-package-compiler"
1949
1949
+
version = "0.25.3"
1950
1950
+
dependencies = [
1951
1951
+
"gleam-core",
1952
1952
+
"im",
1953
1953
+
"insta",
1954
1954
+
"itertools",
1955
1955
+
"toml",
1956
1956
+
]
1957
1957
+
1958
1958
+
[[package]]
1948
1959
name = "textwrap"
1949
1960
version = "0.15.0"
1950
1961
source = "registry+https://github.com/rust-lang/crates.io-index"
+1
Cargo.toml
View file
Reviewed
···
3
3
"compiler-cli",
4
4
"compiler-core",
5
5
"compiler-wasm",
6
6
+
"test-package-compiler",
6
7
]
+1
-1
compiler-core/src/build.rs
View file
Reviewed
···
69
69
70
70
#[derive(Debug)]
71
71
pub struct ErlangAppCodegenConfiguration {
72
72
-
include_dev_deps: bool,
72
72
+
pub include_dev_deps: bool,
73
73
}
74
74
75
75
#[derive(
+2
-1
compiler-core/src/build/package_compilation_tests.rs
View file
Reviewed
···
70
70
};
71
71
}
72
72
73
73
+
// TODO: move this to a test helper crate
73
74
#[derive(Debug)]
74
74
-
struct TestCompileOutput {
75
75
+
pub struct TestCompileOutput {
75
76
files: HashMap<PathBuf, Content>,
76
77
warnings: Vec<crate::Warning>,
77
78
}
+1
-4
compiler-core/src/build/package_compiler.rs
View file
Reviewed
···
36
36
pub root: &'a Path,
37
37
pub target: &'a TargetCodegenConfiguration,
38
38
pub config: &'a PackageConfig,
39
39
+
// TODO: remove this. Tests can use the in memory filesystem instead
39
40
pub sources: Vec<Source>,
40
41
pub ids: UniqueIdGenerator,
41
42
pub write_metadata: bool,
···
47
48
pub build_journal: Option<&'a mut HashSet<PathBuf>>,
48
49
}
49
50
50
50
-
// TODO: ensure this is not a duplicate module
51
51
-
// TODO: tests
52
52
-
// Including cases for:
53
53
-
// - modules that don't import anything
54
51
impl<'a, IO> PackageCompiler<'a, IO>
55
52
where
56
53
IO: FileSystemIO + CommandExecutor + Clone,
+3
-2
compiler-core/src/io/memory.rs
View file
Reviewed
···
1
1
+
use itertools::Itertools;
2
2
+
1
3
use super::*;
2
4
use std::{cell::RefCell, collections::HashMap, ffi::OsStr, rc::Rc};
3
5
···
34
36
.into_inner()
35
37
.into_iter()
36
38
.map(|(path, file)| (path, file.into_content()))
39
39
+
.sorted_by(|a, b| a.0.cmp(&b.0))
37
40
.collect()
38
41
}
39
42
}
···
200
203
}
201
204
}
202
205
203
203
-
// In tests the in memory file system can also be used as a command executor.
204
204
-
#[cfg(test)]
205
206
impl CommandExecutor for InMemoryFileSystem {
206
207
fn exec(
207
208
&self,
+19
test-package-compiler/Cargo.toml
View file
Reviewed
···
1
1
+
[package]
2
2
+
name = "test-package-compiler"
3
3
+
version = "0.25.3"
4
4
+
authors = ["Louis Pilfold <louis@lpil.uk>"]
5
5
+
edition = "2021"
6
6
+
license-file = "LICENCE"
7
7
+
8
8
+
[dependencies]
9
9
+
gleam-core = { path = "../compiler-core" }
10
10
+
# toml config file parsing
11
11
+
toml = "0.5.8"
12
12
+
# Immutable data structures
13
13
+
im = "15.1.0"
14
14
+
# Extra iter methods
15
15
+
itertools = "0.10.1"
16
16
+
17
17
+
[dev-dependencies]
18
18
+
# Snapshot testing to make test maintenance easier
19
19
+
insta = "1.8.0"
+31
test-package-compiler/build.rs
View file
Reviewed
···
1
1
+
use std::path::PathBuf;
2
2
+
3
3
+
pub fn main() {
4
4
+
let mut module = String::new();
5
5
+
6
6
+
let cases = PathBuf::from("./cases")
7
7
+
.canonicalize()
8
8
+
.unwrap()
9
9
+
.parent()
10
10
+
.unwrap()
11
11
+
.to_path_buf()
12
12
+
.join("cases");
13
13
+
14
14
+
for entry in std::fs::read_dir(&cases).unwrap() {
15
15
+
let name = entry.unwrap().file_name().into_string().unwrap();
16
16
+
let path = cases.join(&name);
17
17
+
let path = path.to_str().unwrap();
18
18
+
module.push_str(&format!(
19
19
+
r#"#[test]
20
20
+
fn {name}() {{
21
21
+
let output = crate::prepare("{path}");
22
22
+
insta::assert_snapshot!(insta::internals::AutoName, output, "{path}");
23
23
+
}}
24
24
+
25
25
+
"#
26
26
+
));
27
27
+
}
28
28
+
29
29
+
let out = PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("tests.rs");
30
30
+
std::fs::write(out, module).unwrap();
31
31
+
}
+2
test-package-compiler/cases/hello_joe/gleam.toml
View file
Reviewed
···
1
1
+
name = "hello_joe"
2
2
+
version = "0.1.0"
+3
test-package-compiler/cases/hello_joe/src/hello_joe.gleam
View file
Reviewed
···
1
1
+
pub fn main() {
2
2
+
"Hello, Joe!"
3
3
+
}
+119
test-package-compiler/src/lib.rs
View file
Reviewed
···
1
1
+
// TODO: move TestCompileOutput to a test helper crate
2
2
+
3
3
+
use gleam_core::{
4
4
+
build::{
5
5
+
package_compiler::Source, ErlangAppCodegenConfiguration, Target, TargetCodegenConfiguration,
6
6
+
},
7
7
+
config::PackageConfig,
8
8
+
io::Content,
9
9
+
};
10
10
+
use itertools::Itertools;
11
11
+
use std::{
12
12
+
collections::{HashMap, HashSet},
13
13
+
fmt::Write,
14
14
+
path::PathBuf,
15
15
+
};
16
16
+
17
17
+
pub fn prepare(path: &str) -> String {
18
18
+
let path = PathBuf::from(path);
19
19
+
20
20
+
let toml = std::fs::read_to_string(path.join("gleam.toml")).unwrap();
21
21
+
let config: PackageConfig = toml::from_str(&toml).unwrap();
22
22
+
23
23
+
let sources = path
24
24
+
.join("src")
25
25
+
.read_dir()
26
26
+
.unwrap()
27
27
+
.map(|entry| {
28
28
+
let entry = entry.unwrap();
29
29
+
let localpath = entry.path();
30
30
+
let filename = localpath.file_name().unwrap();
31
31
+
let path = PathBuf::from("src").join(filename);
32
32
+
let name = localpath.file_stem().unwrap().to_string_lossy().to_string();
33
33
+
Source {
34
34
+
code: std::fs::read_to_string(entry.path()).unwrap(),
35
35
+
origin: gleam_core::build::Origin::Src,
36
36
+
path,
37
37
+
name,
38
38
+
}
39
39
+
})
40
40
+
.collect();
41
41
+
42
42
+
let target = match config.target {
43
43
+
Target::Erlang => TargetCodegenConfiguration::Erlang {
44
44
+
app_file: Some(ErlangAppCodegenConfiguration {
45
45
+
include_dev_deps: false,
46
46
+
}),
47
47
+
},
48
48
+
Target::JavaScript => TargetCodegenConfiguration::JavaScript {
49
49
+
emit_typescript_definitions: false,
50
50
+
},
51
51
+
};
52
52
+
53
53
+
let ids = gleam_core::uid::UniqueIdGenerator::new();
54
54
+
let mut modules = im::HashMap::new();
55
55
+
let mut warnings = Vec::new();
56
56
+
let filesystem = gleam_core::io::memory::InMemoryFileSystem::new();
57
57
+
let root = PathBuf::from("/");
58
58
+
let out = PathBuf::from("/out/lib/the_package");
59
59
+
let lib = PathBuf::from("/out/lib");
60
60
+
let mut build_journal = HashSet::new();
61
61
+
let mut compiler = gleam_core::build::PackageCompiler::new(
62
62
+
&config,
63
63
+
&root,
64
64
+
&out,
65
65
+
&lib,
66
66
+
&target,
67
67
+
ids,
68
68
+
filesystem.clone(),
69
69
+
Some(&mut build_journal),
70
70
+
);
71
71
+
compiler.write_entrypoint = false;
72
72
+
compiler.write_metadata = false;
73
73
+
compiler.compile_beam_bytecode = false;
74
74
+
compiler.copy_native_files = false;
75
75
+
compiler.sources = sources;
76
76
+
compiler
77
77
+
.compile(&mut warnings, &mut modules, &mut im::HashMap::new())
78
78
+
.unwrap();
79
79
+
let files = filesystem.into_contents();
80
80
+
TestCompileOutput { files, warnings }.as_overview_text()
81
81
+
}
82
82
+
83
83
+
// TODO: move this to a test helper crate
84
84
+
#[derive(Debug)]
85
85
+
pub struct TestCompileOutput {
86
86
+
files: HashMap<PathBuf, Content>,
87
87
+
warnings: Vec<gleam_core::Warning>,
88
88
+
}
89
89
+
90
90
+
impl TestCompileOutput {
91
91
+
pub fn as_overview_text(&self) -> String {
92
92
+
let mut buffer = String::new();
93
93
+
for (path, content) in self.files.iter().sorted_by(|a, b| a.0.cmp(&b.0)) {
94
94
+
buffer.push_str("//// ");
95
95
+
buffer.push_str(path.to_str().unwrap());
96
96
+
buffer.push('\n');
97
97
+
98
98
+
match content {
99
99
+
Content::Text(text) => buffer.push_str(&text),
100
100
+
Content::Binary(data) => write!(buffer, "{:#?}", data).unwrap(),
101
101
+
};
102
102
+
buffer.push('\n');
103
103
+
buffer.push('\n');
104
104
+
}
105
105
+
106
106
+
for warning in self.warnings.iter() {
107
107
+
write!(buffer, "{:#?}", warning).unwrap();
108
108
+
buffer.push('\n');
109
109
+
buffer.push('\n');
110
110
+
}
111
111
+
112
112
+
buffer
113
113
+
}
114
114
+
}
115
115
+
116
116
+
#[cfg(test)]
117
117
+
mod tests {
118
118
+
include!(concat!(env!("OUT_DIR"), "/tests.rs"));
119
119
+
}