/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/integration/fmt_tests.rs
479 строк
16 KB
Janosh Riebesell
fix(fmt): delegate component expression formatting to markup_fmt (#29763)
24 мар 2026, 21:08
Не верифицирован
24 мар 2026, 21:08
1c50485
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use serde_json::json; use test_util as util; use test_util::test; use util::PathRef; use util::TestContext; use util::TestContextBuilder; use util::assert_contains; use util::assert_not_contains; #[test] fn fmt_test() { let context = TestContext::default(); let t = context.deno_dir(); let testdata_fmt_dir = util::testdata_path().join("fmt"); let fixed_js = testdata_fmt_dir.join("badly_formatted_fixed.js"); let badly_formatted_original_js = testdata_fmt_dir.join("badly_formatted.mjs"); let badly_formatted_js = t.path().join("badly_formatted.js"); badly_formatted_original_js.copy(&badly_formatted_js); let fixed_md = testdata_fmt_dir.join("badly_formatted_fixed.md"); let badly_formatted_original_md = testdata_fmt_dir.join("badly_formatted.md"); let badly_formatted_md = t.path().join("badly_formatted.md"); badly_formatted_original_md.copy(&badly_formatted_md); let fixed_json = testdata_fmt_dir.join("badly_formatted_fixed.json"); let badly_formatted_original_json = testdata_fmt_dir.join("badly_formatted.json"); let badly_formatted_json = t.path().join("badly_formatted.json"); badly_formatted_original_json.copy(&badly_formatted_json); let fixed_css = testdata_fmt_dir.join("badly_formatted_fixed.css"); let badly_formatted_original_css = testdata_fmt_dir.join("badly_formatted.css"); let badly_formatted_css = t.path().join("badly_formatted.css"); badly_formatted_original_css.copy(&badly_formatted_css); let fixed_html = testdata_fmt_dir.join("badly_formatted_fixed.html"); let badly_formatted_original_html = testdata_fmt_dir.join("badly_formatted.html"); let badly_formatted_html = t.path().join("badly_formatted.html"); badly_formatted_original_html.copy(&badly_formatted_html); let fixed_component = testdata_fmt_dir.join("badly_formatted_fixed.svelte"); let badly_formatted_original_component = testdata_fmt_dir.join("badly_formatted.svelte"); let badly_formatted_component = t.path().join("badly_formatted.svelte"); badly_formatted_original_component.copy(&badly_formatted_component); let fixed_ipynb = testdata_fmt_dir.join("badly_formatted_fixed.ipynb"); let badly_formatted_original_ipynb = testdata_fmt_dir.join("badly_formatted.ipynb"); let badly_formatted_ipynb = t.path().join("badly_formatted.ipynb"); badly_formatted_original_ipynb.copy(&badly_formatted_ipynb); let fixed_yaml = testdata_fmt_dir.join("badly_formatted_fixed.yaml"); let badly_formatted_original_yaml = testdata_fmt_dir.join("badly_formatted.yaml"); let badly_formatted_yaml = t.path().join("badly_formatted.yaml"); badly_formatted_original_yaml.copy(&badly_formatted_yaml); let fixed_sql = testdata_fmt_dir.join("badly_formatted_fixed.sql"); let badly_formatted_original_sql = testdata_fmt_dir.join("badly_formatted.sql"); let badly_formatted_sql = t.path().join("badly_formatted.sql"); badly_formatted_original_sql.copy(&badly_formatted_sql); let fixed_vue = testdata_fmt_dir.join("badly_formatted_fixed.vue"); let badly_formatted_original_vue = testdata_fmt_dir.join("badly_formatted.vue"); let badly_formatted_vue = t.path().join("badly_formatted.vue"); badly_formatted_original_vue.copy(&badly_formatted_vue); // First, check formatting by ignoring the badly formatted file. let output = context .new_command() .current_dir(&testdata_fmt_dir) .args_vec(vec![ "fmt".to_string(), "--unstable-css".to_string(), "--unstable-html".to_string(), "--unstable-component".to_string(), "--unstable-yaml".to_string(), "--unstable-sql".to_string(), format!( "--ignore={badly_formatted_js},{badly_formatted_md},{badly_formatted_json},{badly_formatted_css},{badly_formatted_html},{badly_formatted_component},{badly_formatted_yaml},{badly_formatted_ipynb},{badly_formatted_sql},{badly_formatted_vue}", ), format!( "--check {badly_formatted_js} {badly_formatted_md} {badly_formatted_json} {badly_formatted_css} {badly_formatted_html} {badly_formatted_component} {badly_formatted_yaml} {badly_formatted_ipynb} {badly_formatted_sql} {badly_formatted_vue}", ), ]) .run(); // No target files found output.assert_exit_code(1); output.skip_output_check(); // Check without ignore. let output = context .new_command() .current_dir(&testdata_fmt_dir) .args_vec(vec![ "fmt".to_string(), "--check".to_string(), "--unstable-css".to_string(), "--unstable-html".to_string(), "--unstable-component".to_string(), "--unstable-yaml".to_string(), "--unstable-sql".to_string(), badly_formatted_js.to_string(), badly_formatted_md.to_string(), badly_formatted_json.to_string(), badly_formatted_css.to_string(), badly_formatted_html.to_string(), badly_formatted_component.to_string(), badly_formatted_yaml.to_string(), badly_formatted_ipynb.to_string(), badly_formatted_sql.to_string(), badly_formatted_vue.to_string(), ]) .run(); output.assert_exit_code(1); output.skip_output_check(); // Format the source file. let output = context .new_command() .current_dir(&testdata_fmt_dir) .args_vec(vec![ "fmt".to_string(), "--unstable-css".to_string(), "--unstable-html".to_string(), "--unstable-component".to_string(), "--unstable-yaml".to_string(), "--unstable-sql".to_string(), badly_formatted_js.to_string(), badly_formatted_md.to_string(), badly_formatted_json.to_string(), badly_formatted_css.to_string(), badly_formatted_html.to_string(), badly_formatted_component.to_string(), badly_formatted_yaml.to_string(), badly_formatted_ipynb.to_string(), badly_formatted_sql.to_string(), badly_formatted_vue.to_string(), ]) .run(); output.assert_exit_code(0); output.skip_output_check(); let expected_js = fixed_js.read_to_string(); let expected_md = fixed_md.read_to_string(); let expected_json = fixed_json.read_to_string(); let expected_css = fixed_css.read_to_string(); let expected_html = fixed_html.read_to_string(); let expected_component = fixed_component.read_to_string(); let expected_yaml = fixed_yaml.read_to_string(); let expected_ipynb = fixed_ipynb.read_to_string(); let expected_sql = fixed_sql.read_to_string(); let expected_vue = fixed_vue.read_to_string(); let actual_js = badly_formatted_js.read_to_string(); let actual_md = badly_formatted_md.read_to_string(); let actual_json = badly_formatted_json.read_to_string(); let actual_css = badly_formatted_css.read_to_string(); let actual_html = badly_formatted_html.read_to_string(); let actual_component = badly_formatted_component.read_to_string(); let actual_yaml = badly_formatted_yaml.read_to_string(); let actual_ipynb = badly_formatted_ipynb.read_to_string(); let actual_sql = badly_formatted_sql.read_to_string(); let actual_vue = badly_formatted_vue.read_to_string(); assert_eq!(expected_js, actual_js); assert_eq!(expected_md, actual_md); assert_eq!(expected_json, actual_json); assert_eq!(expected_css, actual_css); assert_eq!(expected_html, actual_html); assert_eq!(expected_component, actual_component); assert_eq!(expected_yaml, actual_yaml); assert_eq!(expected_ipynb, actual_ipynb); assert_eq!(expected_sql, actual_sql); assert_eq!(expected_vue, actual_vue); } #[test] fn fmt_stdin_syntax_error() { let output = util::deno_cmd() .current_dir(util::testdata_path()) .arg("fmt") .arg("-") .stdin_text("import { example }") .split_output() .run(); assert!(output.stdout().is_empty()); assert!(!output.stderr().is_empty()); output.assert_exit_code(1); } #[test] fn fmt_auto_ignore_git_and_node_modules() { fn create_bad_json(t: PathRef) { let bad_json_path = t.join("bad.json"); bad_json_path.write("bad json\n"); } let context = TestContext::default(); let temp_dir = context.temp_dir(); let t = temp_dir.path().join("target"); let nest_git = t.join("nest").join(".git"); let git_dir = t.join(".git"); let nest_node_modules = t.join("nest").join("node_modules"); let node_modules_dir = t.join("node_modules"); nest_git.create_dir_all(); git_dir.create_dir_all(); nest_node_modules.create_dir_all(); node_modules_dir.create_dir_all(); create_bad_json(nest_git); create_bad_json(git_dir); create_bad_json(nest_node_modules); create_bad_json(node_modules_dir); let output = context .new_command() .current_dir(t) .env("NO_COLOR", "1") .args("fmt .") .run(); output.assert_exit_code(1); assert_eq!(output.combined_output(), "error: No target files found.\n"); } #[test] fn fmt_with_glob_config() { let context = TestContextBuilder::new().cwd("fmt").build(); let cmd_output = context .new_command() .args("fmt --check --config deno.glob.json") .run(); cmd_output.assert_exit_code(1); let output = cmd_output.combined_output(); if cfg!(windows) { assert_contains!(output, r"glob\nested\fizz\fizz.ts"); assert_contains!(output, r"glob\pages\[id].ts"); assert_contains!(output, r"glob\nested\fizz\bar.ts"); assert_contains!(output, r"glob\nested\foo\foo.ts"); assert_contains!(output, r"glob\data\test1.js"); assert_contains!(output, r"glob\nested\foo\bar.ts"); assert_contains!(output, r"glob\nested\foo\fizz.ts"); assert_contains!(output, r"glob\nested\fizz\foo.ts"); assert_contains!(output, r"glob\data\test1.ts"); } else { assert_contains!(output, "glob/nested/fizz/fizz.ts"); assert_contains!(output, "glob/pages/[id].ts"); assert_contains!(output, "glob/nested/fizz/bar.ts"); assert_contains!(output, "glob/nested/foo/foo.ts"); assert_contains!(output, "glob/data/test1.js"); assert_contains!(output, "glob/nested/foo/bar.ts"); assert_contains!(output, "glob/nested/foo/fizz.ts"); assert_contains!(output, "glob/nested/fizz/foo.ts"); assert_contains!(output, "glob/data/test1.ts"); } assert_contains!(output, "Found 9 not formatted files in 9 files"); } #[test] fn fmt_with_glob_config_and_flags() { let context = TestContextBuilder::new().cwd("fmt").build(); let cmd_output = context .new_command() .args("fmt --check --config deno.glob.json --ignore=glob/nested/**/bar.ts") .run(); cmd_output.assert_exit_code(1); let output = cmd_output.combined_output(); if cfg!(windows) { assert_contains!(output, r"glob\nested\fizz\fizz.ts"); assert_contains!(output, r"glob\pages\[id].ts"); assert_contains!(output, r"glob\nested\fizz\bazz.ts"); assert_contains!(output, r"glob\nested\foo\foo.ts"); assert_contains!(output, r"glob\data\test1.js"); assert_contains!(output, r"glob\nested\foo\bazz.ts"); assert_contains!(output, r"glob\nested\foo\fizz.ts"); assert_contains!(output, r"glob\nested\fizz\foo.ts"); assert_contains!(output, r"glob\data\test1.ts"); } else { assert_contains!(output, "glob/nested/fizz/fizz.ts"); assert_contains!(output, "glob/pages/[id].ts"); assert_contains!(output, "glob/nested/fizz/bazz.ts"); assert_contains!(output, "glob/nested/foo/foo.ts"); assert_contains!(output, "glob/data/test1.js"); assert_contains!(output, "glob/nested/foo/bazz.ts"); assert_contains!(output, "glob/nested/foo/fizz.ts"); assert_contains!(output, "glob/nested/fizz/foo.ts"); assert_contains!(output, "glob/data/test1.ts"); } assert_contains!(output, "Found 9 not formatted files in 9 files"); let cmd_output = context .new_command() .args("fmt --check --config deno.glob.json glob/data/test1.?s") .run(); cmd_output.assert_exit_code(1); let output = cmd_output.combined_output(); if cfg!(windows) { assert_contains!(output, r"glob\data\test1.js"); assert_contains!(output, r"glob\data\test1.ts"); } else { assert_contains!(output, "glob/data/test1.js"); assert_contains!(output, "glob/data/test1.ts"); } assert_contains!(output, "Found 2 not formatted files in 2 files"); } #[test] fn opt_out_top_level_exclude_via_fmt_unexclude() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir().path(); temp_dir.join("deno.json").write_json(&json!({ "fmt": { "exclude": [ "!excluded.ts" ] }, "exclude": [ "excluded.ts", "actually_excluded.ts" ] })); temp_dir.join("main.ts").write("const a = 1;"); temp_dir.join("excluded.ts").write("const a = 2;"); temp_dir .join("actually_excluded.ts") .write("const a = 2;"); let output = context.new_command().arg("fmt").run(); output.assert_exit_code(0); let output = output.combined_output(); assert_contains!(output, "main.ts"); assert_contains!(output, "excluded.ts"); assert_not_contains!(output, "actually_excluded.ts"); } #[test(flaky)] fn test_tty_non_workspace_directory() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir().path(); temp_dir.join("main.ts").write("const a = 1;\n"); context.new_command().arg("fmt").with_pty(|mut pty| { pty.expect("Are you sure you want to format the entire"); pty.write_raw("y\r\n"); pty.expect("Checked 1 file"); }); context.new_command().arg("fmt").with_pty(|mut pty| { pty.expect("Are you sure you want to format"); pty.write_raw("n\r\n"); pty.expect("Did not format non-workspace directory"); }); } #[test] fn fmt_check_fail_fast_stops_on_first_error() { let context = TestContext::default(); let t = context.deno_dir(); // Create multiple badly formatted files let bad1 = t.path().join("bad1.ts"); let bad2 = t.path().join("bad2.ts"); let bad3 = t.path().join("bad3.ts"); bad1.write("const a = 1\n"); bad2.write("const b = 2\n"); bad3.write("const c = 3\n"); // Run with --fail-fast let output = context .new_command() .args_vec(vec![ "fmt".to_string(), "--check".to_string(), "--fail-fast".to_string(), bad1.to_string(), bad2.to_string(), bad3.to_string(), ]) .run(); output.assert_exit_code(1); // Due to parallel processing, multiple files might be checked before // the error flag is set. The important thing is that we exit early // and don't check ALL files. With 3 files, we should see 1-3 reported // (but the flag prevents checking additional files after the first batch). let output_text = output.combined_output(); // Just verify it failed - the exact count depends on parallel execution timing assert_contains!(output_text, "not formatted file"); } #[test] fn fmt_check_fail_fast_with_no_errors() { let context = TestContext::default(); let t = context.deno_dir(); // Create properly formatted files let good1 = t.path().join("good1.ts"); let good2 = t.path().join("good2.ts"); good1.write("const a = 1;\n"); good2.write("const b = 2;\n"); let output = context .new_command() .args_vec(vec![ "fmt".to_string(), "--check".to_string(), "--fail-fast".to_string(), good1.to_string(), good2.to_string(), ]) .run(); output.assert_exit_code(0); assert_contains!(output.combined_output(), "Checked 2 files"); } #[test] fn fmt_check_fail_fast_requires_check() { let context = TestContext::default(); let t = context.deno_dir(); let file = t.path().join("file.ts"); file.write("const a = 1;\n"); let output = context .new_command() .args_vec(vec![ "fmt".to_string(), "--fail-fast".to_string(), file.to_string(), ]) .run(); output.assert_exit_code(1); assert_contains!( output.combined_output(), "the following required arguments were not provided" ); } #[test] fn fmt_check_fail_fast_quiet() { let context = TestContext::default(); let t = context.deno_dir(); let bad1 = t.path().join("bad1.ts"); bad1.write("const a = 1\n"); let output = context .new_command() .args_vec(vec![ "fmt".to_string(), "--check".to_string(), "--fail-fast".to_string(), "--quiet".to_string(), bad1.to_string(), ]) .run(); output.assert_exit_code(1); // With --quiet, errors are still shown but info messages are suppressed let output_text = output.combined_output(); assert_contains!(output_text, "Found 1 not formatted file"); }