1 // Copyright 2011 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "utils/fs/lua_module.hpp" 30 31 #include <atf-c++.hpp> 32 #include <lutok/operations.hpp> 33 #include <lutok/state.hpp> 34 #include <lutok/test_utils.hpp> 35 36 #include "utils/format/macros.hpp" 37 #include "utils/fs/operations.hpp" 38 #include "utils/fs/path.hpp" 39 40 namespace fs = utils::fs; 41 42 43 ATF_TEST_CASE_WITHOUT_HEAD(open_fs); 44 ATF_TEST_CASE_BODY(open_fs) 45 { 46 lutok::state state; 47 stack_balance_checker checker(state); 48 fs::open_fs(state); 49 lutok::do_string(state, "return fs.basename", 0, 1, 0); 50 ATF_REQUIRE(state.is_function(-1)); 51 lutok::do_string(state, "return fs.dirname", 0, 1, 0); 52 ATF_REQUIRE(state.is_function(-1)); 53 lutok::do_string(state, "return fs.join", 0, 1, 0); 54 ATF_REQUIRE(state.is_function(-1)); 55 state.pop(3); 56 } 57 58 59 ATF_TEST_CASE_WITHOUT_HEAD(basename__ok); 60 ATF_TEST_CASE_BODY(basename__ok) 61 { 62 lutok::state state; 63 fs::open_fs(state); 64 65 lutok::do_string(state, "return fs.basename('/my/test//file_foobar')", 66 0, 1, 0); 67 ATF_REQUIRE_EQ("file_foobar", state.to_string(-1)); 68 state.pop(1); 69 } 70 71 72 ATF_TEST_CASE_WITHOUT_HEAD(basename__fail); 73 ATF_TEST_CASE_BODY(basename__fail) 74 { 75 lutok::state state; 76 fs::open_fs(state); 77 78 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string", 79 lutok::do_string(state, "return fs.basename({})", 80 0, 1, 0)); 81 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 82 lutok::do_string(state, "return fs.basename('')", 83 0, 1, 0)); 84 } 85 86 87 ATF_TEST_CASE_WITHOUT_HEAD(dirname__ok); 88 ATF_TEST_CASE_BODY(dirname__ok) 89 { 90 lutok::state state; 91 fs::open_fs(state); 92 93 lutok::do_string(state, "return fs.dirname('/my/test//file_foobar')", 94 0, 1, 0); 95 ATF_REQUIRE_EQ("/my/test", state.to_string(-1)); 96 state.pop(1); 97 } 98 99 100 ATF_TEST_CASE_WITHOUT_HEAD(dirname__fail); 101 ATF_TEST_CASE_BODY(dirname__fail) 102 { 103 lutok::state state; 104 fs::open_fs(state); 105 106 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string", 107 lutok::do_string(state, "return fs.dirname({})", 108 0, 1, 0)); 109 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 110 lutok::do_string(state, "return fs.dirname('')", 111 0, 1, 0)); 112 } 113 114 115 ATF_TEST_CASE_WITHOUT_HEAD(exists__ok); 116 ATF_TEST_CASE_BODY(exists__ok) 117 { 118 lutok::state state; 119 fs::open_fs(state); 120 121 atf::utils::create_file("foo", ""); 122 123 lutok::do_string(state, "return fs.exists('foo')", 0, 1, 0); 124 ATF_REQUIRE(state.to_boolean(-1)); 125 state.pop(1); 126 127 lutok::do_string(state, "return fs.exists('bar')", 0, 1, 0); 128 ATF_REQUIRE(!state.to_boolean(-1)); 129 state.pop(1); 130 131 lutok::do_string(state, 132 F("return fs.exists('%s')") % fs::current_path(), 0, 1, 0); 133 ATF_REQUIRE(state.to_boolean(-1)); 134 state.pop(1); 135 } 136 137 138 ATF_TEST_CASE_WITHOUT_HEAD(exists__fail); 139 ATF_TEST_CASE_BODY(exists__fail) 140 { 141 lutok::state state; 142 fs::open_fs(state); 143 144 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string", 145 lutok::do_string(state, "return fs.exists({})", 146 0, 1, 0)); 147 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 148 lutok::do_string(state, "return fs.exists('')", 149 0, 1, 0)); 150 } 151 152 153 ATF_TEST_CASE_WITHOUT_HEAD(exists__custom_start_dir); 154 ATF_TEST_CASE_BODY(exists__custom_start_dir) 155 { 156 lutok::state state; 157 fs::open_fs(state, fs::path("subdir")); 158 159 fs::mkdir(fs::path("subdir"), 0755); 160 atf::utils::create_file("subdir/foo", ""); 161 atf::utils::create_file("bar", ""); 162 163 lutok::do_string(state, "return fs.exists('foo')", 0, 1, 0); 164 ATF_REQUIRE(state.to_boolean(-1)); 165 state.pop(1); 166 167 lutok::do_string(state, "return fs.exists('subdir/foo')", 0, 1, 0); 168 ATF_REQUIRE(!state.to_boolean(-1)); 169 state.pop(1); 170 171 lutok::do_string(state, "return fs.exists('bar')", 0, 1, 0); 172 ATF_REQUIRE(!state.to_boolean(-1)); 173 state.pop(1); 174 175 lutok::do_string(state, "return fs.exists('../bar')", 0, 1, 0); 176 ATF_REQUIRE(state.to_boolean(-1)); 177 state.pop(1); 178 179 lutok::do_string(state, 180 F("return fs.exists('%s')") % (fs::current_path() / "bar"), 181 0, 1, 0); 182 ATF_REQUIRE(state.to_boolean(-1)); 183 state.pop(1); 184 } 185 186 187 ATF_TEST_CASE_WITHOUT_HEAD(files__none); 188 ATF_TEST_CASE_BODY(files__none) 189 { 190 lutok::state state; 191 state.open_table(); 192 fs::open_fs(state); 193 194 fs::mkdir(fs::path("root"), 0755); 195 196 lutok::do_string(state, 197 "names = {}\n" 198 "for file in fs.files('root') do\n" 199 " table.insert(names, file)\n" 200 "end\n" 201 "table.sort(names)\n" 202 "return table.concat(names, ' ')", 203 0, 1, 0); 204 ATF_REQUIRE_EQ(". ..", state.to_string(-1)); 205 state.pop(1); 206 } 207 208 209 ATF_TEST_CASE_WITHOUT_HEAD(files__some); 210 ATF_TEST_CASE_BODY(files__some) 211 { 212 lutok::state state; 213 state.open_table(); 214 fs::open_fs(state); 215 216 fs::mkdir(fs::path("root"), 0755); 217 atf::utils::create_file("root/file1", ""); 218 atf::utils::create_file("root/file2", ""); 219 220 lutok::do_string(state, 221 "names = {}\n" 222 "for file in fs.files('root') do\n" 223 " table.insert(names, file)\n" 224 "end\n" 225 "table.sort(names)\n" 226 "return table.concat(names, ' ')", 227 0, 1, 0); 228 ATF_REQUIRE_EQ(". .. file1 file2", state.to_string(-1)); 229 state.pop(1); 230 } 231 232 233 ATF_TEST_CASE_WITHOUT_HEAD(files__some_with_custom_start_dir); 234 ATF_TEST_CASE_BODY(files__some_with_custom_start_dir) 235 { 236 lutok::state state; 237 state.open_table(); 238 fs::open_fs(state, fs::current_path() / "root"); 239 240 fs::mkdir(fs::path("root"), 0755); 241 atf::utils::create_file("root/file1", ""); 242 atf::utils::create_file("root/file2", ""); 243 atf::utils::create_file("file3", ""); 244 245 lutok::do_string(state, 246 "names = {}\n" 247 "for file in fs.files('.') do\n" 248 " table.insert(names, file)\n" 249 "end\n" 250 "table.sort(names)\n" 251 "return table.concat(names, ' ')", 252 0, 1, 0); 253 ATF_REQUIRE_EQ(". .. file1 file2", state.to_string(-1)); 254 state.pop(1); 255 } 256 257 258 ATF_TEST_CASE_WITHOUT_HEAD(files__fail_arg); 259 ATF_TEST_CASE_BODY(files__fail_arg) 260 { 261 lutok::state state; 262 fs::open_fs(state); 263 264 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string parameter", 265 lutok::do_string(state, "fs.files({})", 0, 0, 0)); 266 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 267 lutok::do_string(state, "fs.files('')", 0, 0, 0)); 268 } 269 270 271 ATF_TEST_CASE_WITHOUT_HEAD(files__fail_opendir); 272 ATF_TEST_CASE_BODY(files__fail_opendir) 273 { 274 lutok::state state; 275 fs::open_fs(state); 276 277 ATF_REQUIRE_THROW_RE(lutok::error, "Failed to open directory", 278 lutok::do_string(state, "fs.files('root')", 0, 0, 0)); 279 } 280 281 282 ATF_TEST_CASE_WITHOUT_HEAD(is_absolute__ok); 283 ATF_TEST_CASE_BODY(is_absolute__ok) 284 { 285 lutok::state state; 286 fs::open_fs(state); 287 288 lutok::do_string(state, "return fs.is_absolute('my/test//file_foobar')", 289 0, 1, 0); 290 ATF_REQUIRE(!state.to_boolean(-1)); 291 lutok::do_string(state, "return fs.is_absolute('/my/test//file_foobar')", 292 0, 1, 0); 293 ATF_REQUIRE(state.to_boolean(-1)); 294 state.pop(2); 295 } 296 297 298 ATF_TEST_CASE_WITHOUT_HEAD(is_absolute__fail); 299 ATF_TEST_CASE_BODY(is_absolute__fail) 300 { 301 lutok::state state; 302 fs::open_fs(state); 303 304 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string", 305 lutok::do_string(state, "return fs.is_absolute({})", 306 0, 1, 0)); 307 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 308 lutok::do_string(state, "return fs.is_absolute('')", 309 0, 1, 0)); 310 } 311 312 313 ATF_TEST_CASE_WITHOUT_HEAD(join__ok); 314 ATF_TEST_CASE_BODY(join__ok) 315 { 316 lutok::state state; 317 fs::open_fs(state); 318 319 lutok::do_string(state, "return fs.join('/a/b///', 'c/d')", 0, 1, 0); 320 ATF_REQUIRE_EQ("/a/b/c/d", state.to_string(-1)); 321 state.pop(1); 322 } 323 324 325 ATF_TEST_CASE_WITHOUT_HEAD(join__fail); 326 ATF_TEST_CASE_BODY(join__fail) 327 { 328 lutok::state state; 329 fs::open_fs(state); 330 331 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string", 332 lutok::do_string(state, "return fs.join({}, 'a')", 333 0, 1, 0)); 334 ATF_REQUIRE_THROW_RE(lutok::error, "Need a string", 335 lutok::do_string(state, "return fs.join('a', {})", 336 0, 1, 0)); 337 338 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 339 lutok::do_string(state, "return fs.join('', 'a')", 340 0, 1, 0)); 341 ATF_REQUIRE_THROW_RE(lutok::error, "Invalid path", 342 lutok::do_string(state, "return fs.join('a', '')", 343 0, 1, 0)); 344 345 ATF_REQUIRE_THROW_RE(lutok::error, "Cannot join.*'a/b'.*'/c'", 346 lutok::do_string(state, "fs.join('a/b', '/c')", 347 0, 0, 0)); 348 } 349 350 351 ATF_INIT_TEST_CASES(tcs) 352 { 353 ATF_ADD_TEST_CASE(tcs, open_fs); 354 355 ATF_ADD_TEST_CASE(tcs, basename__ok); 356 ATF_ADD_TEST_CASE(tcs, basename__fail); 357 358 ATF_ADD_TEST_CASE(tcs, dirname__ok); 359 ATF_ADD_TEST_CASE(tcs, dirname__fail); 360 361 ATF_ADD_TEST_CASE(tcs, exists__ok); 362 ATF_ADD_TEST_CASE(tcs, exists__fail); 363 ATF_ADD_TEST_CASE(tcs, exists__custom_start_dir); 364 365 ATF_ADD_TEST_CASE(tcs, files__none); 366 ATF_ADD_TEST_CASE(tcs, files__some); 367 ATF_ADD_TEST_CASE(tcs, files__some_with_custom_start_dir); 368 ATF_ADD_TEST_CASE(tcs, files__fail_arg); 369 ATF_ADD_TEST_CASE(tcs, files__fail_opendir); 370 371 ATF_ADD_TEST_CASE(tcs, is_absolute__ok); 372 ATF_ADD_TEST_CASE(tcs, is_absolute__fail); 373 374 ATF_ADD_TEST_CASE(tcs, join__ok); 375 ATF_ADD_TEST_CASE(tcs, join__fail); 376 } 377