Fork of daniellemaywood.uk/gleam — Wasm codegen work
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2022 The Gleam contributors
3
4use std::path::PathBuf;
5
6use camino::{Utf8Path, Utf8PathBuf};
7use gleam_core::Error;
8
9#[test]
10fn new() {
11 let tmp = tempfile::tempdir().unwrap();
12 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
13
14 let creator = super::Creator::new(
15 super::NewOptions {
16 project_root: path.to_string(),
17 template: super::Template::Erlang,
18 name: None,
19 skip_git: false,
20 skip_github: false,
21 },
22 "1.0.0-gleam",
23 )
24 .unwrap();
25
26 creator.run().unwrap();
27
28 assert!(path.join(".git").exists());
29 assert!(path.join("README.md").exists());
30 assert!(path.join("gleam.toml").exists());
31 assert!(path.join("src/my_project.gleam").exists());
32 assert!(path.join("test/my_project_test.gleam").exists());
33 assert!(path.join(".github/workflows/test.yml").exists());
34
35 let toml = crate::fs::read(path.join("gleam.toml")).unwrap();
36 assert!(toml.contains("name = \"my_project\""));
37}
38
39#[test]
40fn new_with_default_template() {
41 let tmp = tempfile::tempdir().unwrap();
42 let path = Utf8PathBuf::from_path_buf(tmp.into_path()).expect("Non Utf8 Path");
43
44 let creator = super::Creator::new(
45 super::NewOptions {
46 project_root: path.join("my_project").to_string(),
47 template: super::Template::Erlang,
48 name: None,
49 skip_git: false,
50 skip_github: true,
51 },
52 "1.0.0-gleam",
53 )
54 .unwrap();
55 creator.run().unwrap();
56
57 insta::glob!(&path, "my_project/[^.]**/*.*", |file_path| {
58 if !file_path.is_dir() {
59 insta::assert_snapshot!(
60 crate::fs::read(
61 Utf8PathBuf::from_path_buf(file_path.to_path_buf()).expect("Non Utf8 Path"),
62 )
63 .unwrap()
64 );
65 }
66 });
67}
68
69#[test]
70fn new_with_javascript_template() {
71 let tmp = tempfile::tempdir().unwrap();
72 let path = Utf8PathBuf::from_path_buf(tmp.into_path()).expect("Non Utf8 Path");
73
74 let creator = super::Creator::new(
75 super::NewOptions {
76 project_root: path.join("my_project").to_string(),
77 template: super::Template::JavaScript,
78 name: None,
79 skip_git: false,
80 skip_github: true,
81 },
82 "1.0.0-gleam",
83 )
84 .unwrap();
85 creator.run().unwrap();
86
87 insta::glob!(&path, "my_project/[^.]**/*.*", |file_path| {
88 if !file_path.is_dir() {
89 insta::assert_snapshot!(
90 crate::fs::read(
91 Utf8PathBuf::from_path_buf(file_path.to_path_buf()).expect("Non Utf8 Path"),
92 )
93 .unwrap()
94 );
95 }
96 });
97}
98
99#[test]
100fn new_with_skip_git() {
101 let tmp = tempfile::tempdir().unwrap();
102 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
103
104 let creator = super::Creator::new(
105 super::NewOptions {
106 project_root: path.to_string(),
107 template: super::Template::Erlang,
108 name: None,
109 skip_git: true,
110 skip_github: false,
111 },
112 "1.0.0-gleam",
113 )
114 .unwrap();
115 creator.run().unwrap();
116 assert!(!path.join(".git").exists());
117 assert!(!path.join(".github").exists());
118}
119
120#[test]
121fn new_with_skip_github() {
122 let tmp = tempfile::tempdir().unwrap();
123 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
124
125 let creator = super::Creator::new(
126 super::NewOptions {
127 project_root: path.to_string(),
128 template: super::Template::Erlang,
129 name: None,
130 skip_git: false,
131 skip_github: true,
132 },
133 "1.0.0-gleam",
134 )
135 .unwrap();
136 creator.run().unwrap();
137
138 assert!(path.join(".git").exists());
139
140 assert!(!path.join(".github").exists());
141 assert!(!path.join(".github/workflows/test.yml").exists());
142}
143
144#[test]
145fn new_with_skip_git_and_github() {
146 let tmp = tempfile::tempdir().unwrap();
147 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
148
149 let creator = super::Creator::new(
150 super::NewOptions {
151 project_root: path.to_string(),
152 template: super::Template::Erlang,
153 name: None,
154 skip_git: true,
155 skip_github: true,
156 },
157 "1.0.0-gleam",
158 )
159 .unwrap();
160 creator.run().unwrap();
161
162 assert!(!path.join(".git").exists());
163
164 assert!(!path.join(".github").exists());
165 assert!(!path.join(".github/workflows/test.yml").exists());
166}
167
168#[test]
169fn invalid_path() {
170 let tmp = tempfile::tempdir().unwrap();
171 let path = Utf8PathBuf::from_path_buf(tmp.path().join("-------")).expect("Non Utf8 Path");
172
173 assert!(
174 super::Creator::new(
175 super::NewOptions {
176 project_root: path.to_string(),
177 template: super::Template::Erlang,
178 name: None,
179 skip_git: false,
180 skip_github: false,
181 },
182 "1.0.0-gleam",
183 )
184 .is_err()
185 );
186}
187
188#[test]
189fn invalid_name() {
190 let tmp = tempfile::tempdir().unwrap();
191 let path = Utf8PathBuf::from_path_buf(tmp.path().join("projec")).expect("Non Utf8 Path");
192
193 assert!(
194 super::Creator::new(
195 super::NewOptions {
196 project_root: path.to_string(),
197 template: super::Template::Erlang,
198 name: Some("-".into()),
199 skip_git: false,
200 skip_github: false,
201 },
202 "1.0.0-gleam",
203 )
204 .is_err()
205 );
206}
207
208#[test]
209fn existing_directory_no_files() {
210 let tmp = tempfile::tempdir().unwrap();
211 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
212
213 crate::fs::mkdir(&path).unwrap();
214
215 let creator = super::Creator::new(
216 super::NewOptions {
217 project_root: path.to_string(),
218 template: super::Template::Erlang,
219 name: None,
220 skip_git: true,
221 skip_github: true,
222 },
223 "1.0.0-gleam",
224 )
225 .unwrap();
226
227 creator.run().unwrap();
228
229 assert!(path.join("README.md").exists());
230}
231
232#[test]
233fn existing_directory_with_one_existing_file() {
234 let tmp = tempfile::tempdir().unwrap();
235 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
236
237 crate::fs::mkdir(&path).unwrap();
238
239 let _ = std::fs::File::create(PathBuf::from(&path).join("README.md")).unwrap();
240 let _ = std::fs::File::create(PathBuf::from(&path).join("my_project.gleam")).unwrap();
241
242 assert!(
243 super::Creator::new(
244 super::NewOptions {
245 project_root: path.to_string(),
246 template: super::Template::Erlang,
247 name: None,
248 skip_git: true,
249 skip_github: true,
250 },
251 "1.0.0-gleam",
252 )
253 .is_err()
254 );
255}
256
257#[test]
258fn existing_directory_with_non_generated_file() {
259 let tmp = tempfile::tempdir().unwrap();
260 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
261
262 crate::fs::mkdir(&path).unwrap();
263 let file_path = PathBuf::from(&path).join("some_fake_thing_that_is_not_generated.md");
264
265 let _ = std::fs::File::create(file_path).unwrap();
266
267 let creator = super::Creator::new(
268 super::NewOptions {
269 project_root: path.to_string(),
270 template: super::Template::Erlang,
271 name: None,
272 skip_git: true,
273 skip_github: true,
274 },
275 "1.0.0-gleam",
276 )
277 .unwrap();
278
279 creator.run().unwrap();
280
281 assert!(path.join("README.md").exists());
282 assert!(
283 path.join("some_fake_thing_that_is_not_generated.md")
284 .exists()
285 );
286}
287
288#[test]
289fn conflict_with_existing_files() {
290 let tmp = tempfile::tempdir().unwrap();
291 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
292
293 crate::fs::mkdir(&path).unwrap();
294
295 let _ = std::fs::File::create(PathBuf::from(&path).join("README.md")).unwrap();
296
297 assert_eq!(
298 super::Creator::new(
299 super::NewOptions {
300 project_root: path.to_string(),
301 template: super::Template::Erlang,
302 name: None,
303 skip_git: true,
304 skip_github: true,
305 },
306 "1.0.0-gleam",
307 )
308 .err(),
309 Some(Error::OutputFilesAlreadyExist {
310 file_names: vec![path.join("README.md")]
311 })
312 );
313}
314
315#[test]
316fn skip_existing_git_files_when_skip_git_is_true() {
317 let tmp = tempfile::tempdir().unwrap();
318 let path = Utf8PathBuf::from_path_buf(tmp.path().join("my_project")).expect("Non Utf8 Path");
319
320 crate::fs::mkdir(&path).unwrap();
321 let file_path = PathBuf::from(&path).join(".gitignore");
322
323 let _ = std::fs::File::create(file_path).unwrap();
324
325 let creator = super::Creator::new(
326 super::NewOptions {
327 project_root: path.to_string(),
328 template: super::Template::Erlang,
329 name: None,
330 skip_git: true,
331 skip_github: true,
332 },
333 "1.0.0-gleam",
334 )
335 .unwrap();
336
337 creator.run().unwrap();
338
339 assert!(path.join("README.md").exists());
340 assert!(path.join(".gitignore").exists());
341}
342
343#[test]
344fn suggested_project_name_updates_directory() {
345 let tmp = tempfile::tempdir().unwrap();
346 let base = Utf8PathBuf::from_path_buf(tmp.path().to_path_buf()).expect("Non Utf8 Path");
347 let original_root = base.join("gleam_testproject");
348
349 let creator = super::Creator::new_with_confirmation(
350 super::NewOptions {
351 project_root: original_root.to_string(),
352 template: super::Template::Erlang,
353 name: None,
354 skip_git: true,
355 skip_github: true,
356 },
357 "1.0.0-gleam",
358 |_| Ok::<bool, Error>(true),
359 )
360 .unwrap();
361
362 let expected_root = base.join("testproject");
363 assert_eq!(creator.project_name, "testproject");
364 assert_eq!(
365 Utf8Path::new(&creator.options.project_root),
366 expected_root.as_path()
367 );
368
369 creator.run().unwrap();
370
371 assert!(expected_root.exists());
372 assert!(!original_root.exists());
373}
374
375#[test]
376fn validate_name_format() {
377 assert!(crate::new::validate_name("project").is_ok());
378 assert!(crate::new::validate_name("project_name").is_ok());
379 assert!(crate::new::validate_name("project2").is_ok());
380
381 let invalid = ["Project", "PROJECT", "Project_Name"];
382 for name in invalid {
383 assert!(matches!(
384 crate::new::validate_name(name),
385 Err(Error::InvalidProjectName {
386 name: _,
387 reason: crate::new::InvalidProjectNameReason::FormatNotLowercase
388 })
389 ));
390 }
391
392 let invalid = ["0project", "_project", "project-name"];
393 for name in invalid {
394 assert!(matches!(
395 crate::new::validate_name(name),
396 Err(Error::InvalidProjectName {
397 name: _,
398 reason: crate::new::InvalidProjectNameReason::Format
399 })
400 ));
401 }
402}
403
404#[test]
405fn suggest_valid_names() {
406 assert_eq!(
407 crate::new::suggest_valid_name(
408 "gleam_",
409 &crate::new::InvalidProjectNameReason::GleamPrefix
410 ),
411 None
412 );
413 assert_eq!(
414 crate::new::suggest_valid_name(
415 "gleam_project",
416 &crate::new::InvalidProjectNameReason::GleamPrefix
417 ),
418 Some("project".to_string())
419 );
420
421 assert_eq!(
422 crate::new::suggest_valid_name(
423 "try",
424 &crate::new::InvalidProjectNameReason::ErlangReservedWord
425 ),
426 Some("try_app".to_string())
427 );
428
429 assert_eq!(
430 crate::new::suggest_valid_name(
431 "erl_eval",
432 &crate::new::InvalidProjectNameReason::ErlangStandardLibraryModule
433 ),
434 Some("erl_eval_app".to_string())
435 );
436
437 assert_eq!(
438 crate::new::suggest_valid_name(
439 "assert",
440 &crate::new::InvalidProjectNameReason::GleamReservedWord
441 ),
442 Some("assert_app".to_string())
443 );
444
445 assert_eq!(
446 crate::new::suggest_valid_name(
447 "gleam",
448 &crate::new::InvalidProjectNameReason::GleamReservedModule
449 ),
450 Some("app_gleam".to_string())
451 );
452
453 assert_eq!(
454 crate::new::suggest_valid_name(
455 "Project_Name",
456 &crate::new::InvalidProjectNameReason::FormatNotLowercase
457 ),
458 Some("project_name".to_string())
459 );
460
461 assert_eq!(
462 crate::new::suggest_valid_name(
463 "Pr0ject-n4me!",
464 &crate::new::InvalidProjectNameReason::Format
465 ),
466 Some("pr0ject_n4me_".to_string())
467 );
468
469 assert_eq!(
470 crate::new::suggest_valid_name(
471 "Pr0ject--n4me!",
472 &crate::new::InvalidProjectNameReason::Format
473 ),
474 Some("pr0ject_n4me_".to_string())
475 );
476
477 assert_eq!(
478 crate::new::suggest_valid_name(
479 "_pr0ject-name",
480 &crate::new::InvalidProjectNameReason::Format
481 ),
482 None
483 );
484}