approvals / ApprovalTests.cpp

Native ApprovalTests for C++ on Linux, Mac and Windows
https://approvaltestscpp.readthedocs.io/en/latest/
Apache License 2.0
318 stars 51 forks source link

"Unable to create directory" - unable to run test build with mingw provided by qt-installer #197

Open Florian-Fischer-InMach opened 2 years ago

Florian-Fischer-InMach commented 2 years ago

Hello, I want to use approval test for some legacy embedded C code. Thus my c++/cmake knowledge is very limited.

My Setup:

I get the same error message as mentioned in #195 I took his example files and created a new cmake project via QT Creator

__FILE__ == C:/Users/florian.fischer/Documents/inmach/src/approvalTest_problem/path_problem_demo/test.cpp

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
path_problem_demo.exe is a Catch v2.13.9 host application.
Run with -? for options

-------------------------------------------------------------------------------
MyTestCase
-------------------------------------------------------------------------------
C:/Users/florian.fischer/Documents/inmach/src/approvalTest_problem/path_problem_demo/test.cpp:5
...............................................................................

C:/Users/florian.fischer/Documents/inmach/src/approvalTest_problem/path_problem_demo/test.cpp:5: FAILED:
due to unexpected exception with message:
  Unable to create directory: 

===============================================================================
test cases: 1 | 1 failed
assertions: 1 | 1 failed

I "solved" it by modifying

std::string SystemUtils::getDirectorySeparator()
{
    //return isWindowsOs() ? "\\" : "/";
    return "/";
}

But then it fails when i want to use AutoApproveIfMissingReporter because copy does not like the paths with / instead of \

Florian-Fischer-InMach commented 2 years ago

After Reading issue #196 i tried to change some settings in QT Creator. By changing the generator from ninja to MinGW Makefiles it works. This is the interesting part of the working output __FILE__ == C:\Users\florian.fischer\Documents\inmach\src\approvalTest_problem\path_problem_demo\test.cpp This time the filename contains backslashes instead of slashes.

Florian-Fischer-InMach commented 2 years ago

I did some more investigation of this issue g++ just copy the filname passed on commandline into FILE when i use this command g++.exe .//////.\\\\./.\\./foo.cpp it prints .//////.\\./.\./foo.cpp

I think you should normalize the Seperators. It seems you have there something prepared.

Path::normalizeSeparators
Path::removeRedundantDirectorySeparators

But according to the debugger in qt-creator they are never called

claremacrae commented 2 years ago

Hello @Florian-Fischer-InMach

Many thanks for this clear report.

We've had a lot of trouble with the Ninja generator previously, and believed that we had worked through all the possible causes.

Here's what we wrote up previously about possible workarounds.

https://approvaltestscpp.readthedocs.io/en/latest/generated_docs/TroubleshootingMisconfiguredBuild.html

If none of those help, would you be interested in pairing with me, via screen sharing from your machine, to find a solution?

Florian-Fischer-InMach commented 2 years ago

Hello @claremacrae Sry for late answer. Was busy with other stuff. I have read the workarounds but they do not solve my problem because they are all about getting abolute Paths. My problem is: Wrong path seperators. Ninja generates paths with "/". getDirectorySeparator returns "\". string magic on path fails because of no match

I changed my Hack from the beginning to this: https://github.com/Florian-Fischer-InMach/ApprovalTests.cpp/commit/84e1a39c27aef9ac1cadaef254c4660ec2cad950

It simply calls normalizeSeparators to fix the sepearators in function setFileName

If you want further discussions we can do a screen sharing to improve this fix

YarikTH commented 7 months ago

I'm cross-compiling from Linux to windows, using mingw. And I bumped into the same problem. I solved it by patching

    std::string ApprovalTestNamer::getSourceFileName() const
    {
        auto file = getCurrentTest().getFileName();
 +       file = Path(file).toString();
        auto start = file.rfind(SystemUtils::getDirectorySeparator()) + 1;
        auto end = file.rfind('.');
        auto fileName = file.substr(start, end - start);
        return convertToFileName(fileName);
    }
...
    std::string FileUtils::getDirectory(const std::string& filePath)
    {
-        auto end = filePath.rfind(SystemUtils::getDirectorySeparator()) + 1;
-        auto directory = filePath.substr(0, end);
+        auto filePath2 = Path(filePath).toString();
+        auto end = filePath2.rfind(SystemUtils::getDirectorySeparator()) + 1;
+        auto directory = filePath2.substr(0, end);
        return directory;
    }

But in the end, https://github.com/Florian-Fischer-InMach/ApprovalTests.cpp/commit/84e1a39c27aef9ac1cadaef254c4660ec2cad950 works as well. Why it is not in the master branch yet? This problem is known for at least 2 years.