Repository: samcrow/canadensis (language: rust)

Issue:
Git path length error on windows
The long filename test breaks git on windows:

```
error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`

Caused by:
  failed to load source for dependency `canadensis`

Caused by:
  Unable to update https://github.com/samcrow/canadensis#9f6553f6

Caused by:
  path too long: 'C:/Users/chemi/.cargo/git/checkouts/canadensis-38552ae0618cb139/9f6553f/canadensis_dsdl_frontend/tests/compile_fail/long_name/canadensis/long_long/TwoHundredAndFiftySixCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan'; class=Filesystem (30)
```

It seems that git for windows (msys) has a 260 character limit for paths. This can be fixed by `git config --system core.longpaths true`, but it would be nice if it worked with defaults.



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab775ae..ac22c81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
+- canadensis_dsdl_frontend: Removed long name DSDL tests from filesystem [#10](https://github.com/samcrow/canadensis/pull/10)
+
 ## [canadensis-v0.2.3](https://github.com/samcrow/canadensis/tree/canadensis-v0.2.3) - 2022-04-12
 
 ### Added


Test patch:
diff --git a/canadensis_dsdl_frontend/tests/compile_fail.rs b/canadensis_dsdl_frontend/tests/compile_fail.rs
index 1d3c615..1cd606f 100644
--- a/canadensis_dsdl_frontend/tests/compile_fail.rs
+++ b/canadensis_dsdl_frontend/tests/compile_fail.rs
@@ -5,6 +5,7 @@
 
 extern crate canadensis_dsdl_frontend;
 
+use canadensis_dsdl_frontend::compiled::package::CompiledPackage;
 use canadensis_dsdl_frontend::{Error, Package};
 use std::ffi::OsString;
 use std::fs;
@@ -25,7 +26,7 @@ fn compile_fail() -> io::Result<()> {
         let case_name = entry.file_name();
 
         match try_compile_package(&entry.path()) {
-            Ok(()) => failed_tests.push(case_name),
+            Ok(_) => failed_tests.push(case_name),
             Err(_) => {}
         }
     }
@@ -37,9 +38,43 @@ fn compile_fail() -> io::Result<()> {
     }
 }
 
-fn try_compile_package(path: &Path) -> Result<(), Error> {
+fn try_compile_package(path: &Path) -> Result<CompiledPackage, Error> {
     let mut package = Package::new();
     package.add_files(path)?;
-    package.compile()?;
-    Ok(())
+    package.compile()
+}
+
+/// Tests a file with a combined path and name that are 256 characters long, which is longer
+/// than the maximum allowed
+///
+/// This is not just a file (like all the other compile-fail cases) because some Windows software
+/// can't handle long paths.
+#[test]
+fn compile_fail_long_name() -> io::Result<()> {
+    let target_dir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
+    let test_dir = target_dir.join("compile_fail_long_name");
+    // The full name of the DSDL type is canadensis.long_long.TwoHundred...
+    let long_name_subdir = test_dir.join("canadensis/long_long");
+    fs::create_dir_all(&long_name_subdir)?;
+    let long_name_file_path = long_name_subdir.join("TwoHundredAndFiftySixCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan");
+    write_long_name_file(&long_name_file_path)?;
+
+    match try_compile_package(&test_dir) {
+        Ok(_) => {
+            panic!("Failed long name compile-fail case");
+        }
+        Err(e) => {
+            assert!(matches!(e, Error::TypeNameLength { .. }));
+            Ok(())
+        }
+    }
+}
+
+fn write_long_name_file(path: &Path) -> io::Result<()> {
+    fs::write(
+        path,
+        "# The path and name of this type are 256 characters long, which is too long.
+@sealed
+",
+    )
 }
diff --git a/canadensis_dsdl_frontend/tests/compile_fail/long_name/canadensis/long_long/TwoHundredAndFiftySixCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan b/canadensis_dsdl_frontend/tests/compile_fail/long_name/canadensis/long_long/TwoHundredAndFiftySixCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan
deleted file mode 100644
index 95094fc..0000000
--- a/canadensis_dsdl_frontend/tests/compile_fail/long_name/canadensis/long_long/TwoHundredAndFiftySixCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan
+++ /dev/null
@@ -1,2 +0,0 @@
-# The path and name of this type are 256 characters long, which is too long.
-@sealed
diff --git a/canadensis_dsdl_frontend/tests/compile_pass.rs b/canadensis_dsdl_frontend/tests/compile_pass.rs
index 196606b..255a0d9 100644
--- a/canadensis_dsdl_frontend/tests/compile_pass.rs
+++ b/canadensis_dsdl_frontend/tests/compile_pass.rs
@@ -4,30 +4,40 @@
 extern crate canadensis_dsdl_frontend;
 
 use canadensis_dsdl_frontend::{Error, Package};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
+use std::{fs, io};
 
 #[test]
 fn compile_simple_types_only() -> Result<(), Error> {
-    test_compile(&["tests/simple_dsdl"])
+    test_compile_subdirs(&["tests/simple_dsdl"])
 }
 #[test]
 fn compile_regulated_types_only() -> Result<(), Error> {
-    test_compile(&["tests/public_regulated_data_types"])
+    test_compile_subdirs(&["tests/public_regulated_data_types"])
 }
 #[test]
 fn compile_all() -> Result<(), Error> {
-    test_compile(&[
+    test_compile_subdirs(&[
         "tests/public_regulated_data_types",
         "tests/nunavut_test_types/test0",
         "tests/simple_dsdl",
     ])
 }
 
-fn test_compile(subdirs: &[&str]) -> Result<(), Error> {
+fn test_compile_subdirs(subdirs: &[&str]) -> Result<(), Error> {
+    let manifset_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
+    let manifest_subdirectories = subdirs.iter().map(|subdir| manifset_dir.join(subdir));
+    test_compile_directories(manifest_subdirectories)
+}
+
+fn test_compile_directories<I, P>(directories: I) -> Result<(), Error>
+where
+    I: IntoIterator<Item = P>,
+    P: AsRef<Path>,
+{
     let mut package = Package::new();
-    for subdir in subdirs {
-        let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(subdir);
-        match package.add_files(path) {
+    for directory in directories {
+        match package.add_files(directory.as_ref()) {
             Ok(()) => {}
             Err(e) => {
                 println!("{}", e);
@@ -43,3 +53,31 @@ fn test_compile(subdirs: &[&str]) -> Result<(), Error> {
         }
     }
 }
+
+/// Tests a file with a combined path and name that are 255 characters long, which is equal
+/// to the maximum allowed length
+///
+/// This is not just a file (like all the other compile cases) because some Windows software
+/// can't handle long paths.
+#[test]
+fn compile_long_name() -> Result<(), Box<dyn std::error::Error>> {
+    let target_dir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
+    let test_dir = target_dir.join("compile_long_name");
+    // The full name of the DSDL type is canadensis.TwoHundred...
+    let long_name_subdir = test_dir.join("canadensis");
+    fs::create_dir_all(&long_name_subdir)?;
+    let long_name_file_path = long_name_subdir.join("TwoHundredAndFiftyFiveCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan");
+    write_long_name_file(&long_name_file_path)?;
+
+    test_compile_directories([test_dir])?;
+    Ok(())
+}
+
+fn write_long_name_file(path: &Path) -> io::Result<()> {
+    fs::write(
+        path,
+        "# The package and name of this type (not including the version) are 255 characters long, which is the maximum allowed.
+@sealed
+",
+    )
+}
diff --git a/canadensis_dsdl_frontend/tests/simple_dsdl/canadensis/TwoHundredAndFiftyFiveCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan b/canadensis_dsdl_frontend/tests/simple_dsdl/canadensis/TwoHundredAndFiftyFiveCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan
deleted file mode 100644
index 90664b9..0000000
--- a/canadensis_dsdl_frontend/tests/simple_dsdl/canadensis/TwoHundredAndFiftyFiveCharactersLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong.1.0.uavcan
+++ /dev/null
@@ -1,2 +0,0 @@
-# The package and name of this type (not including the version) are 255 characters long, which is the maximum allowed.
-@sealed