The Battle for Wesnoth  1.15.1+dev
test_filesystem.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2015 - 2018 by Iris Morelle <shadowm2006@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include <boost/test/unit_test.hpp>
16 #include "filesystem.hpp"
17 #include "game_config.hpp"
18 
19 #if 0
20 namespace {
21 
22 template<typename T>
23 void dump(const T& v)
24 {
25  for(typename T::const_iterator k = v.begin(); k != v.end(); ++k) {
26  std::cerr << " * " << *k << '\n';
27  }
28 }
29 
30 }
31 #endif
32 
33 BOOST_AUTO_TEST_SUITE( filesystem ) // implicit namespace filesystem
34 
35 const std::string& gamedata = game_config::path;
36 
37 BOOST_AUTO_TEST_CASE( test_fs_game_path_reverse_engineering )
38 {
39  const std::string maincfg = "_main.cfg";
40 
41  std::string gamedata_rev = get_wml_location("_main.cfg");
42 
43  const std::size_t strip_len = (maincfg + "/data/").length();
44  BOOST_REQUIRE(gamedata_rev.length() > strip_len);
45  gamedata_rev.resize(gamedata_rev.length() - strip_len);
46 
47  BOOST_CHECK_EQUAL( gamedata_rev, gamedata );
48 }
49 
50 BOOST_AUTO_TEST_CASE( test_fs_base )
51 {
52  BOOST_CHECK( is_root("/") );
53  BOOST_CHECK( is_root("////") );
54  BOOST_CHECK( is_root("/../") );
55  BOOST_CHECK( is_root("/../.././") );
56  BOOST_CHECK( is_root("/.././../.") );
57  BOOST_CHECK( is_root("/.") );
58 
59  BOOST_CHECK( is_relative(".") );
60  BOOST_CHECK( is_relative("..") );
61  BOOST_CHECK( is_relative("../foo") );
62  BOOST_CHECK( is_relative("foo") );
63  BOOST_CHECK( !is_relative("/./../foo/..") );
64  BOOST_CHECK( !is_relative("/foo/..") );
65  BOOST_CHECK( !is_relative("/foo") );
66  BOOST_CHECK( !is_relative("///foo") );
67 
68  BOOST_CHECK( is_directory("/") );
69  BOOST_CHECK( is_directory("/.") );
70  BOOST_CHECK( is_directory("/./././.") );
71  BOOST_CHECK( is_directory("/..") );
72 
73  BOOST_CHECK( is_directory(".") );
74  BOOST_CHECK( is_directory("..") );
75  BOOST_CHECK( is_directory("./././.") );
76 
77  BOOST_CHECK( is_directory(gamedata + "/data/core/../../data/././../data/././core") );
78 
79  BOOST_CHECK( file_exists("/") );
80  BOOST_CHECK( file_exists("/.") );
81  BOOST_CHECK( file_exists("/./././.") );
82  BOOST_CHECK( file_exists("/..") );
83 
84  BOOST_CHECK_EQUAL( base_name("foo/bar/baz.cfg"), "baz.cfg" );
85  // FIXME: BFS gives "." for this, Unix basename gives "bar"!
86  //BOOST_CHECK_EQUAL( base_name("foo/bar/"), "bar" );
87  BOOST_CHECK_EQUAL( base_name("foo/bar"), "bar" );
88  BOOST_CHECK_EQUAL( base_name("/"), "/" );
89  BOOST_CHECK_EQUAL( base_name(""), "" );
90 
91  BOOST_CHECK_EQUAL( directory_name("foo/bar/baz.cfg"), "foo/bar" );
92  BOOST_CHECK_EQUAL( directory_name("foo/bar/"), "foo/bar" );
93  BOOST_CHECK_EQUAL( directory_name("foo/bar"), "foo" );
94  BOOST_CHECK_EQUAL( directory_name("/"), "" );
95  BOOST_CHECK_EQUAL( directory_name(""), "" );
96 
97  // TODO normalize_path
98 
99  //BOOST_CHECK_EQUAL( normalize_path(gamedata + "/data/core/../../data/././../data/././core"),
100  // gamedata + "/data/core" );
101 }
102 
103 BOOST_AUTO_TEST_CASE( test_fs_enum )
104 {
105  const std::string path = "data/test/test/filesystem/enum";
106 
107  const std::vector<std::string> expected_filenames {
108  "_initial.cfg",
109  "A1.cfg",
110  "A2.cfg",
111  "A3.cfg",
112  "B1.cfg",
113  "B2.cfg",
114  "B3.cfg",
115  "_final.cfg"};
116  const std::vector<std::string> expected_dirnames {
117  "D1",
118  "D2",
119  "D3"};
120 
121  std::vector<std::string> files, dirs;
122  std::vector<std::string> expected_filepaths, expected_dirpaths;
123 
124  for(const std::string& n : expected_filenames) {
125  expected_filepaths.push_back(gamedata + "/" + path + "/" + n);
126  }
127 
128  for(const std::string& n : expected_dirnames) {
129  expected_dirpaths.push_back(gamedata + "/" + path + "/" + n);
130  }
131 
132  // FIXME: get_files_in_dir with mode == FILE_NAME_ONLY will fail to reorder
133  // entries because the sorting code looks for forward slashes.
134  // This affects both the BFS-based and legacy implementations.
135  get_files_in_dir(path, &files, &dirs, ENTIRE_FILE_PATH, NO_FILTER, DO_REORDER);
136 
137  BOOST_CHECK( files == expected_filepaths );
138  BOOST_CHECK( dirs == expected_dirpaths );
139 }
140 
141 BOOST_AUTO_TEST_CASE( test_fs_binary_path )
142 {
143  BOOST_CHECK_EQUAL( get_binary_dir_location("images", "."), gamedata + "/images/." );
144 
145  BOOST_CHECK_EQUAL( get_binary_file_location("images", "././././././"),
146  gamedata + "/images/././././././" );
147 
148  BOOST_CHECK_EQUAL( get_binary_file_location("images", "wesnoth-icon.png"),
149  gamedata + "/data/core/images/wesnoth-icon.png" );
150 
151  BOOST_CHECK_EQUAL( get_binary_file_location("music", "silence.ogg"),
152  gamedata + "/data/core/music/silence.ogg" );
153 
154  BOOST_CHECK_EQUAL( get_binary_file_location("sounds", "explosion.ogg"),
155  gamedata + "/data/core/sounds/explosion.ogg" );
156 
157  BOOST_CHECK_EQUAL( get_independent_image_path("wesnoth-icon.png"),
158  "data/core/images/wesnoth-icon.png" );
159 
160  // Inexistent paths are resolved empty.
161  BOOST_CHECK( get_binary_dir_location("images", "").empty() );
162  BOOST_CHECK( get_binary_dir_location("inexistent_resource_type", "").empty() );
163  BOOST_CHECK( get_binary_file_location("image", "wesnoth-icon.png").empty() );
164  BOOST_CHECK( get_binary_file_location("images", "bunnies_and_ponies_and_rainbows_oh_em_gee.psd").empty() );
165  BOOST_CHECK( get_binary_file_location("music", "this_track_does_not_exist.aiff").empty() );
166  BOOST_CHECK( get_binary_file_location("sounds", "rude_noises.aiff").empty() );
167  BOOST_CHECK( get_independent_image_path("dopefish.txt").empty() );
168 }
169 
170 BOOST_AUTO_TEST_CASE( test_fs_wml_path )
171 {
172  const std::string& userdata = get_user_data_dir();
173 
174  BOOST_CHECK_EQUAL( get_wml_location(""), "" );
175 
176  BOOST_CHECK_EQUAL( get_wml_location("_main.cfg"), gamedata + "/data/_main.cfg" );
177  BOOST_CHECK_EQUAL( get_wml_location("core/_main.cfg"), gamedata + "/data/core/_main.cfg" );
178  BOOST_CHECK_EQUAL( get_wml_location("."), gamedata + "/data/." );
179 
180  BOOST_CHECK_EQUAL( get_wml_location("~/"), userdata + "/data/" );
181 
182  // Inexistent paths are resolved empty.
183  BOOST_CHECK( get_wml_location("why_would_anyone_ever_name_a_file_like_this").empty() );
184 }
185 
186 BOOST_AUTO_TEST_CASE( test_fs_search )
187 {
188  const std::string& userdata = get_user_data_dir();
189 
190  BOOST_CHECK_EQUAL( nearest_extant_parent(userdata + "/THIS_DOES_NOT_EXIST/foo/bar"), userdata );
191 
192  BOOST_CHECK_EQUAL( nearest_extant_parent(gamedata + "/THIS_DOES_NOT_EXIST_EITHER/foo"), gamedata );
193  BOOST_CHECK_EQUAL( nearest_extant_parent(gamedata + "/data/_main.cfg"), gamedata + "/data" );
194  BOOST_CHECK_EQUAL( nearest_extant_parent(gamedata + "/data/core/THIS_DOES_NOT_EXIST/test"), gamedata + "/data/core" );
195 
196  BOOST_CHECK_EQUAL( nearest_extant_parent("/THIS_HOPEFULLY_DOES_NOT_EXIST"), "/" );
197  BOOST_CHECK_EQUAL( nearest_extant_parent("/THIS_HOPEFULLY_DOES_NOT_EXIST/foo/bar"), "/" );
198  BOOST_CHECK_EQUAL( nearest_extant_parent("/THIS_HOPEFULLY_DOES_NOT_EXIST/foo/bar/.."), "/" );
199 }
200 
201 BOOST_AUTO_TEST_CASE( test_fs_fluff )
202 {
203  BOOST_CHECK( ends_with("foobarbazbat", "bazbat") );
204 
205  BOOST_CHECK( looks_like_pbl("foo.pbl") );
206  BOOST_CHECK( looks_like_pbl("FOO.PBL") );
207  BOOST_CHECK( looks_like_pbl("Foo.Pbl") );
208  BOOST_CHECK( !looks_like_pbl("foo.pbl.cfg") );
209 
210  BOOST_CHECK( is_gzip_file("foo.gz") );
211  BOOST_CHECK( !is_gzip_file("foo.gz.bz2") );
212  BOOST_CHECK( is_bzip2_file("foo.bz2") );
213  BOOST_CHECK( !is_bzip2_file("foo.bz2.gz") );
214 
215  BOOST_CHECK( is_compressed_file("foo.gz") );
216  BOOST_CHECK( is_compressed_file("foo.bz2") );
217  BOOST_CHECK( !is_compressed_file("foo.txt") );
218 
219  // FIXME: Is this even intended?
220  BOOST_CHECK( !is_gzip_file("foo.GZ") );
221  BOOST_CHECK( !is_bzip2_file("foo.BZ2") );
222  BOOST_CHECK( !is_compressed_file("foo.GZ") );
223  BOOST_CHECK( !is_compressed_file("foo.BZ2") );
224 }
225 
226 BOOST_AUTO_TEST_SUITE_END()
std::string get_binary_dir_location(const std::string &type, const std::string &filename)
Returns a complete path to the actual directory of a given type or an empty string if the directory i...
BOOST_AUTO_TEST_SUITE(filesystem) const std BOOST_AUTO_TEST_CASE(test_fs_game_path_reverse_engineering)
bool looks_like_pbl(const std::string &file)
static bool file_exists(const bfs::path &fpath)
Definition: filesystem.cpp:282
bool ends_with(const std::string &str, const std::string &suffix)
std::string get_binary_file_location(const std::string &type, const std::string &filename)
Returns a complete path to the actual file of a given type or an empty string if the file isn&#39;t prese...
game_data * gamedata
Definition: resources.cpp:22
std::string get_user_data_dir()
Definition: filesystem.cpp:775
std::string nearest_extant_parent(const std::string &file)
Finds the nearest parent in existence for a file or directory.
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
std::string path
Definition: game_config.cpp:39
std::string get_independent_image_path(const std::string &filename)
Returns an image path to filename for binary path-independent use in saved games. ...
bool is_gzip_file(const std::string &filename)
Returns true if the file ends with &#39;.gz&#39;.
void get_files_in_dir(const std::string &dir, std::vector< std::string > *files, std::vector< std::string > *dirs, file_name_option mode, file_filter_option filter, file_reorder_option reorder, file_tree_checksum *checksum)
Populates &#39;files&#39; with all the files and &#39;dirs&#39; with all the directories in dir.
Definition: filesystem.cpp:368
bool is_relative(const std::string &path)
Returns whether the path seems to be relative.
std::string get_wml_location(const std::string &filename, const std::string &current_dir)
Returns a complete path to the actual WML file or directory or an empty string if the file isn&#39;t pres...
bool is_compressed_file(const std::string &filename)
Definition: filesystem.hpp:230
bool is_root(const std::string &path)
Returns whether the path is the root of the file hierarchy.
Declarations for File-IO.
std::string base_name(const std::string &file, const bool remove_extension)
Returns the base filename of a file, with directory name stripped.
bool is_bzip2_file(const std::string &filename)
Returns true if the file ends with &#39;.bz2&#39;.
static map_location::DIRECTION n
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.