KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_filename_resolver.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
24
26
27// Code under test
28#include <filename_resolver.h>
29#include <search_stack.h>
30
31#include <wx/filename.h>
32
33#include <filesystem>
34#include <fstream>
35
36namespace fs = std::filesystem;
37
38BOOST_AUTO_TEST_SUITE( FilenameResolver )
39
40BOOST_AUTO_TEST_CASE( ResolveAbsoluteAndWorkingPath )
41{
42 fs::path temp = fs::temp_directory_path() / "fnres_test";
43 fs::create_directories( temp );
44
45 fs::path work = temp / "work";
46 fs::create_directories( work );
47
48 fs::path file = work / "model.txt";
49 std::ofstream( file.string() ) << "dummy";
50
52
53 wxString absFile = wxString::FromUTF8( file.string() );
54 wxString resolved = resolver.ResolvePath( absFile, wxEmptyString, {} );
55 wxFileName fn( absFile );
56 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
57 BOOST_CHECK_EQUAL( resolved, fn.GetFullPath() );
58
59 wxString working = wxString::FromUTF8( work.string() );
60 wxString relResolved = resolver.ResolvePath( wxS( "model.txt" ), working, {} );
61 BOOST_CHECK_EQUAL( relResolved, fn.GetFullPath() );
62}
63
64BOOST_AUTO_TEST_CASE( ResolveAliasAndErrors )
65{
66 fs::path temp = fs::temp_directory_path() / "fnres_alias";
67 fs::create_directories( temp );
68
69 fs::path file = temp / "a.txt";
70 std::ofstream( file.string() ) << "dummy";
71
73
74 SEARCH_PATH sp;
75 sp.m_Alias = wxS( "ALIAS" );
76 sp.m_Pathvar = wxString::FromUTF8( temp.string() );
77 std::vector<SEARCH_PATH> paths = { sp };
78 resolver.UpdatePathList( paths );
79
80 // canonical ALIAS:path format (no leading colon)
81 wxString resolved = resolver.ResolvePath( wxS( "ALIAS:a.txt" ), wxEmptyString, {} );
82 BOOST_CHECK_EQUAL( resolved, wxString::FromUTF8( file.string() ) );
83
84 // legacy :ALIAS:path format (leading colon)
85 wxString resolvedLeadingColon = resolver.ResolvePath( wxS( ":ALIAS:a.txt" ), wxEmptyString, {} );
86 BOOST_CHECK_EQUAL( resolvedLeadingColon, wxString::FromUTF8( file.string() ) );
87
88 // unknown alias returns empty
89 wxString missing = resolver.ResolvePath( wxS( "MISSING:a.txt" ), wxEmptyString, {} );
90 BOOST_CHECK( missing.IsEmpty() );
91}
92
93// Verify that ShortenPath outputs ${ALIAS}/path and that the result round-trips through ResolvePath.
94BOOST_AUTO_TEST_CASE( ShortenPathRoundTrip )
95{
96 fs::path temp = fs::temp_directory_path() / "fnres_shorten";
97 fs::create_directories( temp );
98
99 fs::path file = temp / "sub" / "model.wrl";
100 fs::create_directories( file.parent_path() );
101 std::ofstream( file.string() ) << "dummy";
102
104
105 SEARCH_PATH sp;
106 sp.m_Alias = wxS( "MYLIB" );
107 sp.m_Pathvar = wxString::FromUTF8( temp.string() );
108 resolver.UpdatePathList( { sp } );
109
110 wxString full = wxString::FromUTF8( file.string() );
111 wxString shortened = resolver.ShortenPath( full );
112
113 // ShortenPath produces ${ALIAS}/path for user-defined aliases
114 BOOST_CHECK( shortened.StartsWith( wxS( "${MYLIB}/" ) ) );
115
116 // The shortened path must resolve back to the original file
117 wxString resolvedBack = resolver.ResolvePath( shortened, wxEmptyString, {} );
118 wxFileName fn( full );
119 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
120 BOOST_CHECK_EQUAL( resolvedBack, fn.GetFullPath() );
121}
122
123// Backward compatibility: files saved by older KiCad versions with :ALIAS:path format
124// for user-defined aliases must still resolve correctly.
125BOOST_AUTO_TEST_CASE( ResolveBackCompatColonAlias )
126{
127 fs::path temp = fs::temp_directory_path() / "fnres_colon_alias";
128 fs::create_directories( temp );
129
130 fs::path file = temp / "model.wrl";
131 std::ofstream( file.string() ) << "dummy";
132
134
135 SEARCH_PATH sp;
136 sp.m_Alias = wxS( "MYLIB" );
137 sp.m_Pathvar = wxString::FromUTF8( temp.string() );
138 resolver.UpdatePathList( { sp } );
139
140 // :MYLIB:model.wrl is the legacy format produced by KiCad before e7d6c84aef
141 wxString resolved = resolver.ResolvePath( wxS( ":MYLIB:model.wrl" ), wxEmptyString, {} );
142 wxFileName fn( wxString::FromUTF8( file.string() ) );
143 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
144 BOOST_CHECK_EQUAL( resolved, fn.GetFullPath() );
145}
146
148
149BOOST_AUTO_TEST_SUITE( SearchStack )
150
151BOOST_AUTO_TEST_CASE( RelativePathResolution )
152{
153 fs::path root = fs::temp_directory_path() / "ss_root";
154 fs::path sub = root / "sub";
155 fs::create_directories( sub );
156
157 fs::path file = sub / "f.txt";
158 std::ofstream( file.string() ) << "dummy";
159
160 SEARCH_STACK stack;
161 stack.AddPaths( wxString::FromUTF8( root.string() ) );
162
163 wxString rel = stack.FilenameWithRelativePathInSearchList( wxString::FromUTF8( file.string() ),
164 wxString::FromUTF8( root.string() ) );
165 BOOST_CHECK_EQUAL( rel, wxString::FromUTF8( ( fs::path( "sub" ) / "f.txt" ).string() ) );
166
167 fs::path outside = fs::temp_directory_path() / "outside.txt";
168 std::ofstream( outside.string() ) << "dummy";
169
170 wxString full = stack.FilenameWithRelativePathInSearchList( wxString::FromUTF8( outside.string() ),
171 wxString::FromUTF8( root.string() ) );
172 BOOST_CHECK_EQUAL( full, wxString::FromUTF8( outside.string() ) );
173}
174
Provide an extensible class to resolve 3D model paths.
Look for files in a number of paths.
void AddPaths(const wxString &aPaths, int aIndex=-1)
Insert or append path(s).
wxString FilenameWithRelativePathInSearchList(const wxString &aFullFilename, const wxString &aBaseDir)
Return the shortest possible path which can be use later to find a full path from this SEARCH_STACK.
static FILENAME_RESOLVER * resolver
wxString m_Pathvar
Base path as stored in the configuration file.
wxString m_Alias
Alias to the base path.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(ResolveAbsoluteAndWorkingPath)
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(result, "25.4")