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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
28
30
31// Code under test
32#include <filename_resolver.h>
33#include <search_stack.h>
34
35#include <wx/filename.h>
36
37#include <filesystem>
38#include <fstream>
39
40namespace fs = std::filesystem;
41
42BOOST_AUTO_TEST_SUITE( FilenameResolver )
43
44BOOST_AUTO_TEST_CASE( ResolveAbsoluteAndWorkingPath )
45{
46 fs::path temp = fs::temp_directory_path() / "fnres_test";
47 fs::create_directories( temp );
48
49 fs::path work = temp / "work";
50 fs::create_directories( work );
51
52 fs::path file = work / "model.txt";
53 std::ofstream( file.string() ) << "dummy";
54
56
57 wxString absFile = wxString::FromUTF8( file.string() );
58 wxString resolved = resolver.ResolvePath( absFile, wxEmptyString, {} );
59 wxFileName fn( absFile );
60 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
61 BOOST_CHECK_EQUAL( resolved, fn.GetFullPath() );
62
63 wxString working = wxString::FromUTF8( work.string() );
64 wxString relResolved = resolver.ResolvePath( wxS( "model.txt" ), working, {} );
65 BOOST_CHECK_EQUAL( relResolved, fn.GetFullPath() );
66}
67
68BOOST_AUTO_TEST_CASE( ResolveAliasAndErrors )
69{
70 fs::path temp = fs::temp_directory_path() / "fnres_alias";
71 fs::create_directories( temp );
72
73 fs::path file = temp / "a.txt";
74 std::ofstream( file.string() ) << "dummy";
75
77
78 SEARCH_PATH sp;
79 sp.m_Alias = wxS( "ALIAS" );
80 sp.m_Pathvar = wxString::FromUTF8( temp.string() );
81 std::vector<SEARCH_PATH> paths = { sp };
82 resolver.UpdatePathList( paths );
83
84 // canonical ALIAS:path format (no leading colon)
85 wxString resolved = resolver.ResolvePath( wxS( "ALIAS:a.txt" ), wxEmptyString, {} );
86 BOOST_CHECK_EQUAL( resolved, wxString::FromUTF8( file.string() ) );
87
88 // legacy :ALIAS:path format (leading colon)
89 wxString resolvedLeadingColon = resolver.ResolvePath( wxS( ":ALIAS:a.txt" ), wxEmptyString, {} );
90 BOOST_CHECK_EQUAL( resolvedLeadingColon, wxString::FromUTF8( file.string() ) );
91
92 // unknown alias returns empty
93 wxString missing = resolver.ResolvePath( wxS( "MISSING:a.txt" ), wxEmptyString, {} );
94 BOOST_CHECK( missing.IsEmpty() );
95}
96
97// Verify that ShortenPath outputs ${ALIAS}/path and that the result round-trips through ResolvePath.
98BOOST_AUTO_TEST_CASE( ShortenPathRoundTrip )
99{
100 fs::path temp = fs::temp_directory_path() / "fnres_shorten";
101 fs::create_directories( temp );
102
103 fs::path file = temp / "sub" / "model.wrl";
104 fs::create_directories( file.parent_path() );
105 std::ofstream( file.string() ) << "dummy";
106
108
109 SEARCH_PATH sp;
110 sp.m_Alias = wxS( "MYLIB" );
111 sp.m_Pathvar = wxString::FromUTF8( temp.string() );
112 resolver.UpdatePathList( { sp } );
113
114 wxString full = wxString::FromUTF8( file.string() );
115 wxString shortened = resolver.ShortenPath( full );
116
117 // ShortenPath produces ${ALIAS}/path for user-defined aliases
118 BOOST_CHECK( shortened.StartsWith( wxS( "${MYLIB}/" ) ) );
119
120 // The shortened path must resolve back to the original file
121 wxString resolvedBack = resolver.ResolvePath( shortened, wxEmptyString, {} );
122 wxFileName fn( full );
123 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
124 BOOST_CHECK_EQUAL( resolvedBack, fn.GetFullPath() );
125}
126
127// Backward compatibility: files saved by older KiCad versions with :ALIAS:path format
128// for user-defined aliases must still resolve correctly.
129BOOST_AUTO_TEST_CASE( ResolveBackCompatColonAlias )
130{
131 fs::path temp = fs::temp_directory_path() / "fnres_colon_alias";
132 fs::create_directories( temp );
133
134 fs::path file = temp / "model.wrl";
135 std::ofstream( file.string() ) << "dummy";
136
138
139 SEARCH_PATH sp;
140 sp.m_Alias = wxS( "MYLIB" );
141 sp.m_Pathvar = wxString::FromUTF8( temp.string() );
142 resolver.UpdatePathList( { sp } );
143
144 // :MYLIB:model.wrl is the legacy format produced by KiCad before e7d6c84aef
145 wxString resolved = resolver.ResolvePath( wxS( ":MYLIB:model.wrl" ), wxEmptyString, {} );
146 wxFileName fn( wxString::FromUTF8( file.string() ) );
147 fn.Normalize( wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS );
148 BOOST_CHECK_EQUAL( resolved, fn.GetFullPath() );
149}
150
152
153BOOST_AUTO_TEST_SUITE( SearchStack )
154
155BOOST_AUTO_TEST_CASE( RelativePathResolution )
156{
157 fs::path root = fs::temp_directory_path() / "ss_root";
158 fs::path sub = root / "sub";
159 fs::create_directories( sub );
160
161 fs::path file = sub / "f.txt";
162 std::ofstream( file.string() ) << "dummy";
163
164 SEARCH_STACK stack;
165 stack.AddPaths( wxString::FromUTF8( root.string() ) );
166
167 wxString rel = stack.FilenameWithRelativePathInSearchList( wxString::FromUTF8( file.string() ),
168 wxString::FromUTF8( root.string() ) );
169 BOOST_CHECK_EQUAL( rel, wxString::FromUTF8( ( fs::path( "sub" ) / "f.txt" ).string() ) );
170
171 fs::path outside = fs::temp_directory_path() / "outside.txt";
172 std::ofstream( outside.string() ) << "dummy";
173
174 wxString full = stack.FilenameWithRelativePathInSearchList( wxString::FromUTF8( outside.string() ),
175 wxString::FromUTF8( root.string() ) );
176 BOOST_CHECK_EQUAL( full, wxString::FromUTF8( outside.string() ) );
177}
178
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")