diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c9feace..9496c9f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -62,5 +62,6 @@ jobs: ./target ~/.cargo key: ${{ runner.os }}-cargo-dev-${{ hashFiles('**/Cargo.lock') }} + - run: cargo test --all-targets --all-features - run: bash test/test_all.sh - run: git diff --exit-code --quiet || exit 1 diff --git a/Cargo.lock b/Cargo.lock index d9946d0..fe6a020 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,23 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata 0.1.10", +] + [[package]] name = "cc" version = "1.0.83" @@ -60,13 +77,25 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.2.1", "strsim", "textwrap", "unicode-width", "vec_map", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys", +] + [[package]] name = "convert_case" version = "0.6.0" @@ -76,6 +105,28 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "generator" version = "0.7.5" @@ -89,6 +140,18 @@ dependencies = [ "windows", ] +[[package]] +name = "goldenfile" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d5c44265baec620ea19c97b4ce9f068e28f8c3d7faccc483f02968b5e3c587" +dependencies = [ + "scopeguard", + "similar-asserts", + "tempfile", + "yansi", +] + [[package]] name = "heck" version = "0.3.1" @@ -121,9 +184,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" @@ -275,6 +344,19 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -302,6 +384,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.193" @@ -342,6 +430,26 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "similar" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +dependencies = [ + "bstr", + "unicode-segmentation", +] + +[[package]] +name = "similar-asserts" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e041bb827d1bfca18f213411d51b665309f1afb37a04a5d1464530e13779fc0f" +dependencies = [ + "console", + "similar", +] + [[package]] name = "smallvec" version = "1.11.2" @@ -409,6 +517,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -494,6 +614,7 @@ name = "tsync" version = "2.2.0" dependencies = [ "convert_case", + "goldenfile", "proc-macro2", "quote", "serde", @@ -599,7 +720,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", ] [[package]] @@ -608,13 +738,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -623,38 +769,92 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" diff --git a/Cargo.toml b/Cargo.toml index aa8e7af..3cbb965 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ state = "0.6.0" [dev-dependencies] serde = { version = "1", features = ["derive"] } +goldenfile = "1.7.1" [lib] name = "tsync" diff --git a/tests/codegen.rs b/tests/codegen.rs new file mode 100644 index 0000000..ef86a96 --- /dev/null +++ b/tests/codegen.rs @@ -0,0 +1,222 @@ +//! Note: if multiple tests that use the same goldenfile are run in parallel, there may be a race condition. + +use goldenfile::Mint; + +use std::{io::Write, path::PathBuf}; + +/// Register the goldenfiles for a specific test. +/// This function returns a mint that, when dropped, will compare the "goldenfiles" to the actual output. +/// If they differ, the test will fail. +fn register_goldenfile>(mint: &mut Mint, base_path: P, name: &str) { + // Register the goldenfile + let mut golden = mint.new_goldenfile(name).unwrap(); + + // Fill the goldenfile with the current content of the file. + golden + .write_all(&std::fs::read(base_path.as_ref().join(name)).unwrap()) + .unwrap(); +} + +/// Teardown the mint. +/// When the mint is dropped, it will compare the goldenfiles to the actual output. +/// But we also want to reset the goldenfiles to their original state. +fn teardown_mint(mint: Mint) { + // check the goldenfiles, and catch the panic if one occurs so we can reset the goldenfiles afterwards. + let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + mint.check_goldenfiles(); + })); + + // reset the goldenfiles to their original state. + mint.update_goldenfiles(); + + // if the check_goldenfiles panicked, panic again. + if let Err(err) = res { + std::panic::resume_unwind(err); + } + + // drop the mint + drop(mint); +} + +#[test] +fn test_const() { + let base_path = PathBuf::from("test/const"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, false); + tsync::generate_typescript_defs(vec![input], output2, false, false); + + // Compare the generated files to the checked-in golden files + teardown_mint(mint); +} + +#[test] +fn test_const_enum_numeric() { + let base_path = PathBuf::from("test/const_enum_numeric"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, true); + tsync::generate_typescript_defs(vec![input], output2, false, true); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_directory_input() { + let base_path = PathBuf::from("test/directory_input"); + let input = base_path.join("directory"); + let output = base_path.join("typescript.d.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input], output, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_doc_comments() { + let base_path = PathBuf::from("test/doc_comments"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, false); + tsync::generate_typescript_defs(vec![input], output2, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_enum() { + let base_path = PathBuf::from("test/enum"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, false); + tsync::generate_typescript_defs(vec![input], output2, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_enum_numeric() { + let base_path = PathBuf::from("test/enum_numeric"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, false); + tsync::generate_typescript_defs(vec![input], output2, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_generic() { + let base_path = PathBuf::from("test/generic"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, false); + tsync::generate_typescript_defs(vec![input], output2, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_struct() { + let base_path = PathBuf::from("test/struct"); + let input = base_path.join("rust.rs"); + let output1 = base_path.join("typescript.d.ts"); + let output2 = base_path.join("typescript.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + register_goldenfile(&mut mint, &base_path, "typescript.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input.clone()], output1, false, false); + tsync::generate_typescript_defs(vec![input], output2, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +} + +#[test] +fn test_type() { + let base_path = PathBuf::from("test/type"); + let input = base_path.join("rust.rs"); + let output = base_path.join("typescript.d.ts"); + + // Create a new goldenfile mint + let mut mint = Mint::new(&base_path); + // Register the goldenfiles + register_goldenfile(&mut mint, &base_path, "typescript.d.ts"); + + // Generate the typescript definitions + tsync::generate_typescript_defs(vec![input], output, false, false); + + // Compare the generated files to the checked-in golden files and reset the goldenfiles + teardown_mint(mint); +}