facter 3.9.6.cfacter.20180612 → 3.11.0.cfacter.20180319

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/ext/facter/facter/CMakeLists.txt +1 -1
  3. data/ext/facter/facter/acceptance/Gemfile +3 -4
  4. data/ext/facter/facter/acceptance/Rakefile +342 -2
  5. data/ext/facter/facter/acceptance/config/aio/options.rb +6 -0
  6. data/ext/facter/facter/acceptance/config/git/options.rb +5 -1
  7. data/ext/facter/facter/acceptance/setup/aio/pre-suite/010_Install.rb +22 -0
  8. data/ext/facter/facter/acceptance/setup/aio/pre-suite/021_InstallAristaModule.rb +12 -0
  9. data/ext/facter/facter/acceptance/setup/aio/pre-suite/022_Remove_LD_PRELOAD.rb +11 -0
  10. data/ext/facter/facter/acceptance/setup/common/00_EnvSetup.rb +64 -0
  11. data/ext/facter/facter/acceptance/setup/common/pre-suite/000-delete-puppet-when-none.rb +11 -0
  12. data/ext/facter/facter/acceptance/setup/git/pre-suite/01_TestSetup.rb +31 -0
  13. data/ext/facter/facter/acceptance/tests/ticket_1238_hostname_fqdn.rb +20 -0
  14. data/ext/facter/facter/lib/CMakeLists.txt +3 -2
  15. data/ext/facter/facter/lib/Doxyfile +1 -1
  16. data/ext/facter/facter/lib/inc/facter/facts/fact.hpp +5 -0
  17. data/ext/facter/facter/lib/inc/internal/facts/aix/networking_resolver.hpp +0 -7
  18. data/ext/facter/facter/lib/inc/internal/facts/freebsd/networking_resolver.hpp +0 -7
  19. data/ext/facter/facter/lib/inc/internal/facts/linux/fips_resolver.hpp +31 -0
  20. data/ext/facter/facter/lib/inc/internal/facts/linux/networking_resolver.hpp +0 -7
  21. data/ext/facter/facter/lib/inc/internal/facts/openbsd/networking_resolver.hpp +0 -7
  22. data/ext/facter/facter/lib/inc/internal/facts/osx/networking_resolver.hpp +0 -7
  23. data/ext/facter/facter/lib/inc/internal/facts/posix/networking_resolver.hpp +0 -7
  24. data/ext/facter/facter/lib/inc/internal/facts/resolvers/fips_resolver.hpp +46 -0
  25. data/ext/facter/facter/lib/inc/internal/facts/resolvers/networking_resolver.hpp +2 -3
  26. data/ext/facter/facter/lib/inc/internal/facts/resolvers/ssh_resolver.hpp +6 -0
  27. data/ext/facter/facter/lib/inc/internal/facts/solaris/networking_resolver.hpp +0 -7
  28. data/ext/facter/facter/lib/schema/facter.yaml +38 -18
  29. data/ext/facter/facter/lib/src/cwrapper.cc +5 -0
  30. data/ext/facter/facter/lib/src/facts/aix/disk_resolver.cc +2 -11
  31. data/ext/facter/facter/lib/src/facts/aix/networking_resolver.cc +0 -5
  32. data/ext/facter/facter/lib/src/facts/freebsd/dmi_resolver.cc +5 -1
  33. data/ext/facter/facter/lib/src/facts/freebsd/networking_resolver.cc +1 -10
  34. data/ext/facter/facter/lib/src/facts/freebsd/virtualization_resolver.cc +1 -4
  35. data/ext/facter/facter/lib/src/facts/linux/collection.cc +2 -0
  36. data/ext/facter/facter/lib/src/facts/linux/fips_resolver.cc +31 -0
  37. data/ext/facter/facter/lib/src/facts/linux/networking_resolver.cc +1 -10
  38. data/ext/facter/facter/lib/src/facts/openbsd/networking_resolver.cc +1 -10
  39. data/ext/facter/facter/lib/src/facts/osx/networking_resolver.cc +1 -10
  40. data/ext/facter/facter/lib/src/facts/posix/networking_resolver.cc +2 -3
  41. data/ext/facter/facter/lib/src/facts/posix/ssh_resolver.cc +3 -2
  42. data/ext/facter/facter/lib/src/facts/resolvers/fips_resolver.cc +23 -0
  43. data/ext/facter/facter/lib/src/facts/resolvers/networking_resolver.cc +7 -23
  44. data/ext/facter/facter/lib/src/facts/resolvers/ssh_resolver.cc +1 -0
  45. data/ext/facter/facter/lib/src/facts/solaris/networking_resolver.cc +0 -5
  46. data/ext/facter/facter/lib/tests/facts/resolvers/ssh_resolver.cc +8 -1
  47. data/ext/facter/facter/lib/tests/facts/schema.cc +17 -0
  48. data/ext/facter/facter/locales/FACTER.pot +2 -23
  49. data/ext/facter/leatherman/CHANGELOG.md +16 -9
  50. data/ext/facter/leatherman/CMakeLists.txt +1 -2
  51. data/ext/facter/leatherman/appveyor.yml +26 -19
  52. data/ext/facter/leatherman/catch/CMakeLists.txt +1 -1
  53. data/ext/facter/leatherman/curl/tests/client_test.cc +396 -398
  54. data/ext/facter/leatherman/curl/tests/mock_curl.cc +2 -0
  55. data/ext/facter/leatherman/curl/tests/request_test.cc +66 -68
  56. data/ext/facter/leatherman/curl/tests/response_test.cc +50 -52
  57. data/ext/facter/leatherman/dynamic_library/tests/dynamic_library_tests.cc +71 -75
  58. data/ext/facter/leatherman/execution/src/execution.cc +3 -0
  59. data/ext/facter/leatherman/execution/src/posix/execution.cc +5 -6
  60. data/ext/facter/leatherman/execution/src/windows/execution.cc +2 -0
  61. data/ext/facter/leatherman/execution/tests/windows/execution.cc +4 -2
  62. data/ext/facter/leatherman/file_util/tests/directory_utils_test.cc +66 -68
  63. data/ext/facter/leatherman/file_util/tests/file_utils_test.cc +175 -177
  64. data/ext/facter/leatherman/json_container/inc/leatherman/json_container/json_container.hpp +7 -0
  65. data/ext/facter/leatherman/json_container/src/json_container.cc +10 -1
  66. data/ext/facter/leatherman/json_container/tests/json_container_test.cc +152 -8
  67. data/ext/facter/leatherman/locale/CMakeLists.txt +0 -7
  68. data/ext/facter/leatherman/locales/leatherman.pot +8 -13
  69. data/ext/facter/leatherman/logging/src/logging.cc +2 -0
  70. data/ext/facter/leatherman/util/tests/timer.cc +1 -3
  71. data/ext/facter/leatherman/vendor/Catch-1.10.0.zip +0 -0
  72. data/ext/facter/leatherman/vendor/nowide/doc/Doxyfile +4 -4
  73. data/ext/facter/leatherman/vendor/nowide/doc/LICENSE_1_0.txt +23 -0
  74. data/ext/facter/leatherman/vendor/nowide/doc/main.txt +62 -54
  75. data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/convert.hpp +16 -16
  76. data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/cstdio.hpp +4 -4
  77. data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/utf8_codecvt.hpp +1 -1
  78. data/ext/facter/leatherman/vendor/nowide/src/iostream.cpp +32 -30
  79. data/ext/facter/leatherman/vendor/nowide/standalone/convert +6 -6
  80. data/ext/facter/leatherman/vendor/nowide/standalone/encoding_utf.hpp +1 -1
  81. data/ext/facter/leatherman/vendor/nowide/standalone/run_convert_and_build.sh +1 -3
  82. metadata +15 -6
  83. data/ext/facter/leatherman/cmake/FindICU.cmake +0 -690
  84. data/ext/facter/leatherman/scripts/travis_target.sh +0 -79
  85. data/ext/facter/leatherman/vendor/catch-1.4.0.zip +0 -0
@@ -161,6 +161,7 @@ namespace leatherman { namespace execution {
161
161
  // Represents information about a pipe
162
162
  struct pipe
163
163
  {
164
+ // cppcheck-suppress passedByValue
164
165
  pipe(string pipe_name, scoped_descriptor desc, function<bool(string const&)> cb) :
165
166
  name(move(pipe_name)),
166
167
  descriptor(move(desc)),
@@ -169,6 +170,7 @@ namespace leatherman { namespace execution {
169
170
  {
170
171
  }
171
172
 
173
+ // cppcheck-suppress passedByValue
172
174
  pipe(string pipe_name, scoped_descriptor desc, string buf) :
173
175
  name(move(pipe_name)),
174
176
  descriptor(move(desc)),
@@ -221,8 +223,7 @@ namespace leatherman { namespace execution {
221
223
  int result = select(max + 1, &read_set, &write_set, nullptr, timeout ? &read_timeout : nullptr);
222
224
  if (result == -1) {
223
225
  if (errno != EINTR) {
224
- LOG_ERROR(format_error(_("select call failed")));
225
- throw execution_exception(_("child i/o failed."));
226
+ throw execution_exception(format_error(_("select call failed waiting for child i/o")));
226
227
  }
227
228
  // Interrupted by signal
228
229
  LOG_DEBUG("select call was interrupted and will be retried.");
@@ -505,15 +506,13 @@ namespace leatherman { namespace execution {
505
506
  struct sigaction sa = {};
506
507
  sa.sa_handler = timer_handler;
507
508
  if (sigaction(SIGALRM, &sa, nullptr) == -1) {
508
- LOG_ERROR(format_error(_("sigaction failed")));
509
- throw execution_exception(format_error(_("failed to setup timer")));
509
+ throw execution_exception(format_error(_("sigaction failed while setting up timeout")));
510
510
  }
511
511
 
512
512
  itimerval timer = {};
513
513
  timer.it_value.tv_sec = static_cast<decltype(timer.it_interval.tv_sec)>(timeout);
514
514
  if (setitimer(ITIMER_REAL, &timer, nullptr) == -1) {
515
- LOG_ERROR(format_error(_("setitimer failed")));
516
- throw execution_exception(format_error(_("failed to setup timer")));
515
+ throw execution_exception(format_error(_("setitimer failed while setting up timeout")));
517
516
  }
518
517
 
519
518
  // Set the resource to disable the timer
@@ -215,6 +215,7 @@ namespace leatherman { namespace execution {
215
215
  // Represents information about a pipe
216
216
  struct pipe
217
217
  {
218
+ // cppcheck-suppress passedByValue
218
219
  pipe(string pipe_name, scoped_handle pipe_handle, function<bool(string const&)> cb) :
219
220
  name(move(pipe_name)),
220
221
  handle(move(pipe_handle)),
@@ -226,6 +227,7 @@ namespace leatherman { namespace execution {
226
227
  init();
227
228
  }
228
229
 
230
+ // cppcheck-suppress passedByValue
229
231
  pipe(string pipe_name, scoped_handle pipe_handle, string buf) :
230
232
  name(move(pipe_name)),
231
233
  handle(move(pipe_handle)),
@@ -143,8 +143,10 @@ SCENARIO("executing commands with execution::execute") {
143
143
  auto exec = execute("cmd.exe", { "/c", CMAKE_BIN_DIRECTORY "/lth_cat.exe", "prefix", "suffix", "overwhelm", "stderr" },
144
144
  "hello\ngoodbye", 0, { execution_options::merge_environment });
145
145
  REQUIRE(exec.success);
146
- REQUIRE(exec.output == lth_cat::prefix+lth_cat::overwhelm+"hello\n"+lth_cat::overwhelm+"goodbye\n"+lth_cat::overwhelm+lth_cat::suffix);
147
- REQUIRE(exec.error == "hello\ngoodbye\n");
146
+ auto expected = lth_cat::prefix+lth_cat::overwhelm+"hello\n"+lth_cat::overwhelm+"goodbye\n"+lth_cat::overwhelm+lth_cat::suffix;
147
+ boost::replace_all(expected, "\n", "\r\n");
148
+ REQUIRE(exec.output == expected);
149
+ REQUIRE(exec.error == "hello\r\ngoodbye\r\n");
148
150
  REQUIRE(exec.exit_code == 0);
149
151
  }
150
152
  WHEN("requested to write stdout to file") {
@@ -4,86 +4,84 @@
4
4
  #include "fixtures.hpp"
5
5
  #include <boost/filesystem.hpp>
6
6
 
7
- namespace leatherman { namespace file_util {
7
+ using namespace leatherman::file_util;
8
8
 
9
- TEST_CASE("file_util::each_file", "[utils]") {
9
+ TEST_CASE("file_util::each_file", "[utils]") {
10
10
 
11
- temp_directory directory;
12
- atomic_write_to_file("1\n", directory.get_dir_name() + "/test1");
13
- atomic_write_to_file("2\n", directory.get_dir_name() + "/test2");
14
- atomic_write_to_file("3\n", directory.get_dir_name() + "/test3");
11
+ temp_directory directory;
12
+ atomic_write_to_file("1\n", directory.get_dir_name() + "/test1");
13
+ atomic_write_to_file("2\n", directory.get_dir_name() + "/test2");
14
+ atomic_write_to_file("3\n", directory.get_dir_name() + "/test3");
15
15
 
16
- SECTION("each file should be visited") {
17
- std::set<std::string> file_contents;
18
- each_file(directory.get_dir_name(), [&file_contents](std::string const &path) {
19
- file_contents.insert(read(path));
20
- return true;
21
- });
22
- REQUIRE(file_contents.size() == 3u);
23
- REQUIRE(file_contents.find("1\n") != file_contents.end());
24
- REQUIRE(file_contents.find("2\n") != file_contents.end());
25
- REQUIRE(file_contents.find("3\n") != file_contents.end());
26
- }
27
-
28
- SECTION("can find a file to match a pattern") {
29
- std::string content = "N/A";
30
- each_file(directory.get_dir_name(), [&content](std::string const &path) {
31
- return read(path, content);
32
- }, "[0-1]");
33
- REQUIRE(content == "1\n");
34
- }
16
+ SECTION("each file should be visited") {
17
+ std::set<std::string> file_contents;
18
+ each_file(directory.get_dir_name(), [&file_contents](std::string const &path) {
19
+ file_contents.insert(read(path));
20
+ return true;
21
+ });
22
+ REQUIRE(file_contents.size() == 3u);
23
+ REQUIRE(file_contents.find("1\n") != file_contents.end());
24
+ REQUIRE(file_contents.find("2\n") != file_contents.end());
25
+ REQUIRE(file_contents.find("3\n") != file_contents.end());
26
+ }
35
27
 
36
- SECTION("only one file returned from false callback"){
37
- int count = 0;
38
- each_file(directory.get_dir_name(), [&count](std::string const& path){
39
- count++;
40
- return false;
41
- });
42
- REQUIRE(count == 1);
43
- }
28
+ SECTION("can find a file to match a pattern") {
29
+ std::string content = "N/A";
30
+ each_file(directory.get_dir_name(), [&content](std::string const &path) {
31
+ return read(path, content);
32
+ }, "[0-1]");
33
+ REQUIRE(content == "1\n");
34
+ }
44
35
 
36
+ SECTION("only one file returned from false callback"){
37
+ int count = 0;
38
+ each_file(directory.get_dir_name(), [&count](std::string const& path){
39
+ count++;
40
+ return false;
41
+ });
42
+ REQUIRE(count == 1);
45
43
  }
46
44
 
47
- TEST_CASE("file_util::each_subdirectory", "[utils]") {
48
- temp_directory directory;
49
- boost::filesystem::create_directory(directory.get_dir_name() + "/test1");
50
- atomic_write_to_file("1", directory.get_dir_name() + "/test1/t1");
51
- boost::filesystem::create_directory(directory.get_dir_name() + "/test2");
52
- atomic_write_to_file("2a", directory.get_dir_name() + "/test2/t2a");
53
- atomic_write_to_file("2b", directory.get_dir_name() + "/test2/t2b");
45
+ }
46
+
47
+ TEST_CASE("file_util::each_subdirectory", "[utils]") {
48
+ temp_directory directory;
49
+ boost::filesystem::create_directory(directory.get_dir_name() + "/test1");
50
+ atomic_write_to_file("1", directory.get_dir_name() + "/test1/t1");
51
+ boost::filesystem::create_directory(directory.get_dir_name() + "/test2");
52
+ atomic_write_to_file("2a", directory.get_dir_name() + "/test2/t2a");
53
+ atomic_write_to_file("2b", directory.get_dir_name() + "/test2/t2b");
54
54
 
55
- SECTION("each subdirectory should be visited") {
56
- int counter = 0;
57
- each_subdirectory(directory.get_dir_name(), [&counter](std::string const &path) {
58
- each_file(path, [&counter](std::string const &file) {
59
- counter++;
60
- return true;
61
- });
55
+ SECTION("each subdirectory should be visited") {
56
+ int counter = 0;
57
+ each_subdirectory(directory.get_dir_name(), [&counter](std::string const &path) {
58
+ each_file(path, [&counter](std::string const &file) {
59
+ counter++;
62
60
  return true;
63
61
  });
64
- REQUIRE(counter == 3);
65
- }
62
+ return true;
63
+ });
64
+ REQUIRE(counter == 3);
65
+ }
66
66
 
67
- SECTION("can find directories that match a pattern") {
68
- int counter = 0;
69
- each_subdirectory(directory.get_dir_name(), [&counter](std::string const &path) {
70
- each_file(path, [&counter](std::string const &file) {
71
- counter++;
72
- return true;
73
- });
67
+ SECTION("can find directories that match a pattern") {
68
+ int counter = 0;
69
+ each_subdirectory(directory.get_dir_name(), [&counter](std::string const &path) {
70
+ each_file(path, [&counter](std::string const &file) {
71
+ counter++;
74
72
  return true;
75
- }, "[2-3]");
76
- REQUIRE(counter == 2);
77
- }
78
-
79
- SECTION("only one directory found from false callback"){
80
- int count = 0;
81
- each_subdirectory(directory.get_dir_name(), [&count](std::string const& path){
82
- count++;
83
- return false;
84
73
  });
85
- REQUIRE(count == 1);
86
- }
74
+ return true;
75
+ }, "[2-3]");
76
+ REQUIRE(counter == 2);
87
77
  }
88
78
 
89
- }} //namespace leatherman::file_util
79
+ SECTION("only one directory found from false callback"){
80
+ int count = 0;
81
+ each_subdirectory(directory.get_dir_name(), [&count](std::string const& path){
82
+ count++;
83
+ return false;
84
+ });
85
+ REQUIRE(count == 1);
86
+ }
87
+ }
@@ -7,191 +7,189 @@
7
7
  #include <windows.h>
8
8
  #endif
9
9
 
10
- namespace leatherman { namespace file_util {
10
+ using namespace leatherman::file_util;
11
11
 
12
- TEST_CASE("file_util::tilde_expand", "[utils]") {
12
+ TEST_CASE("file_util::tilde_expand", "[utils]") {
13
13
 
14
14
  #ifdef _WIN32
15
- _putenv("USERPROFILE=/testhome");
15
+ _putenv("USERPROFILE=/testhome");
16
16
  #else
17
- setenv("HOME", "/testhome", 1);
17
+ setenv("HOME", "/testhome", 1);
18
18
  #endif
19
19
 
20
- SECTION("empty path should be empty") {
21
- REQUIRE(tilde_expand("") == "");
22
- }
23
-
24
- SECTION("spaces should be preserved") {
25
- REQUIRE(tilde_expand("i like spaces") == "i like spaces");
26
- }
27
-
28
- SECTION("should expand using environment variable") {
29
- CHECK(tilde_expand("~") == "/testhome");
30
- CHECK(tilde_expand("~/") == "/testhome/");
31
- CHECK(tilde_expand("~/foo") == "/testhome/foo");
32
- }
33
-
34
- SECTION("only a ~ at the start") {
35
- REQUIRE(tilde_expand("/foo/bar~") == "/foo/bar~");
36
- }
37
-
38
- SECTION("~baz/foo does not expand") {
39
- REQUIRE(tilde_expand("~baz/foo") == "~baz/foo");
40
- }
41
-
42
- SECTION("it should expand the home directory path") {
43
- REQUIRE(tilde_expand("~/foo") != "~/foo");
44
- }
45
-
46
- SECTION("it should not expand the working directory path") {
47
- REQUIRE(tilde_expand("./foo") == "./foo");
48
- }
49
-
50
- auto home_path = get_home_path();
51
-
52
- SECTION("it should expand ~ to the HOME env var") {
53
- REQUIRE(tilde_expand("~") == home_path);
54
- }
55
-
56
- SECTION("it should expand ~ as the base directory") {
57
- std::string expected_path{home_path + "/spam"};
58
- std::string expanded_path{tilde_expand("~/spam")};
59
- REQUIRE(expanded_path == expected_path);
60
- }
61
- }
62
-
63
- TEST_CASE("shell_quote", "[utils]") {
64
- SECTION("empty string") {
65
- REQUIRE(shell_quote("") == "\"\"");
66
- }
67
-
68
- SECTION("single word") {
69
- REQUIRE(shell_quote("plain") == "\"plain\"");
70
- }
71
-
72
- SECTION("words separated by space") {
73
- REQUIRE(shell_quote("a space") == "\"a space\"");
74
- }
75
-
76
- SECTION("exclamation mark") {
77
- REQUIRE(shell_quote("!csh") == "\"!csh\"");
78
- }
79
-
80
- SECTION("single quote before expression") {
81
- REQUIRE(shell_quote("'open quote") == "\"'open quote\"");
82
- }
83
-
84
- SECTION("single quote after expression") {
85
- REQUIRE(shell_quote("close quote'") == "\"close quote'\"");
86
- }
87
-
88
- SECTION("double quote before expression") {
89
- REQUIRE(shell_quote("\"open doublequote")
90
- == "\"\\\"open doublequote\"");
91
- }
92
-
93
- SECTION("double quote after expression") {
94
- REQUIRE(shell_quote("close doublequote\"")
95
- == "\"close doublequote\\\"\"");
96
- }
97
- }
98
-
99
- TEST_CASE("lth_file::file_readable", "[utils]") {
100
- SECTION("it can check that a file does not exist") {
101
- auto file_path = unique_fixture_path().string();
102
- CAPTURE(file_path);
103
- REQUIRE_FALSE(file_readable(file_path));
104
- }
105
-
106
- SECTION("directories are not readable") {
107
- temp_directory dir_path;
108
- REQUIRE_FALSE(file_readable(dir_path.get_dir_name()));
109
- }
110
- }
111
-
112
- TEST_CASE("lth_file::atomic_write_to_file", "[utils]") {
113
- SECTION("it can write to a regular file, ensure it exists, and delete it") {
114
- auto file_path = unique_fixture_path().string();
115
- REQUIRE_FALSE(file_readable(file_path));
116
- atomic_write_to_file("test\n", file_path);
117
- REQUIRE(file_readable(file_path));
118
- boost::filesystem::remove(file_path);
119
- REQUIRE_FALSE(file_readable(file_path));
120
- }
121
-
122
- SECTION("can write to an existing file") {
123
- temp_file file("existing file");
124
- REQUIRE(file_readable(file.get_file_name()));
125
- atomic_write_to_file("test", file.get_file_name());
126
- REQUIRE(file_readable(file.get_file_name()));
127
- REQUIRE(read(file.get_file_name()) == "test");
128
- }
20
+ SECTION("empty path should be empty") {
21
+ REQUIRE(tilde_expand("") == "");
22
+ }
23
+
24
+ SECTION("spaces should be preserved") {
25
+ REQUIRE(tilde_expand("i like spaces") == "i like spaces");
26
+ }
27
+
28
+ SECTION("should expand using environment variable") {
29
+ CHECK(tilde_expand("~") == "/testhome");
30
+ CHECK(tilde_expand("~/") == "/testhome/");
31
+ CHECK(tilde_expand("~/foo") == "/testhome/foo");
32
+ }
33
+
34
+ SECTION("only a ~ at the start") {
35
+ REQUIRE(tilde_expand("/foo/bar~") == "/foo/bar~");
36
+ }
37
+
38
+ SECTION("~baz/foo does not expand") {
39
+ REQUIRE(tilde_expand("~baz/foo") == "~baz/foo");
40
+ }
41
+
42
+ SECTION("it should expand the home directory path") {
43
+ REQUIRE(tilde_expand("~/foo") != "~/foo");
44
+ }
45
+
46
+ SECTION("it should not expand the working directory path") {
47
+ REQUIRE(tilde_expand("./foo") == "./foo");
48
+ }
49
+
50
+ auto home_path = get_home_path();
51
+
52
+ SECTION("it should expand ~ to the HOME env var") {
53
+ REQUIRE(tilde_expand("~") == home_path);
54
+ }
55
+
56
+ SECTION("it should expand ~ as the base directory") {
57
+ std::string expected_path{home_path + "/spam"};
58
+ std::string expanded_path{tilde_expand("~/spam")};
59
+ REQUIRE(expanded_path == expected_path);
60
+ }
61
+ }
62
+
63
+ TEST_CASE("shell_quote", "[utils]") {
64
+ SECTION("empty string") {
65
+ REQUIRE(shell_quote("") == "\"\"");
66
+ }
67
+
68
+ SECTION("single word") {
69
+ REQUIRE(shell_quote("plain") == "\"plain\"");
70
+ }
71
+
72
+ SECTION("words separated by space") {
73
+ REQUIRE(shell_quote("a space") == "\"a space\"");
74
+ }
75
+
76
+ SECTION("exclamation mark") {
77
+ REQUIRE(shell_quote("!csh") == "\"!csh\"");
78
+ }
79
+
80
+ SECTION("single quote before expression") {
81
+ REQUIRE(shell_quote("'open quote") == "\"'open quote\"");
82
+ }
83
+
84
+ SECTION("single quote after expression") {
85
+ REQUIRE(shell_quote("close quote'") == "\"close quote'\"");
86
+ }
87
+
88
+ SECTION("double quote before expression") {
89
+ REQUIRE(shell_quote("\"open doublequote")
90
+ == "\"\\\"open doublequote\"");
91
+ }
92
+
93
+ SECTION("double quote after expression") {
94
+ REQUIRE(shell_quote("close doublequote\"")
95
+ == "\"close doublequote\\\"\"");
96
+ }
97
+ }
98
+
99
+ TEST_CASE("lth_file::file_readable", "[utils]") {
100
+ SECTION("it can check that a file does not exist") {
101
+ auto file_path = unique_fixture_path().string();
102
+ CAPTURE(file_path);
103
+ REQUIRE_FALSE(file_readable(file_path));
104
+ }
105
+
106
+ SECTION("directories are not readable") {
107
+ temp_directory dir_path;
108
+ REQUIRE_FALSE(file_readable(dir_path.get_dir_name()));
109
+ }
110
+ }
111
+
112
+ TEST_CASE("lth_file::atomic_write_to_file", "[utils]") {
113
+ SECTION("it can write to a regular file, ensure it exists, and delete it") {
114
+ auto file_path = unique_fixture_path().string();
115
+ REQUIRE_FALSE(file_readable(file_path));
116
+ atomic_write_to_file("test\n", file_path);
117
+ REQUIRE(file_readable(file_path));
118
+ boost::filesystem::remove(file_path);
119
+ REQUIRE_FALSE(file_readable(file_path));
120
+ }
121
+
122
+ SECTION("can write to an existing file") {
123
+ temp_file file("existing file");
124
+ REQUIRE(file_readable(file.get_file_name()));
125
+ atomic_write_to_file("test", file.get_file_name());
126
+ REQUIRE(file_readable(file.get_file_name()));
127
+ REQUIRE(read(file.get_file_name()) == "test");
128
+ }
129
129
 
130
130
  #ifndef _WIN32
131
- SECTION("can write a file with permissions") {
132
- auto file_path = unique_fixture_path().string();
133
- REQUIRE_FALSE(file_readable(file_path));
134
- auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write;
135
- atomic_write_to_file("test\n", file_path, perms, std::ios::binary);
136
- REQUIRE(file_readable(file_path));
137
- auto stat = boost::filesystem::status(file_path);
138
- REQUIRE(stat.permissions() == perms);
139
- boost::filesystem::remove(file_path);
140
- REQUIRE_FALSE(file_readable(file_path));
141
- }
131
+ SECTION("can write a file with permissions") {
132
+ auto file_path = unique_fixture_path().string();
133
+ REQUIRE_FALSE(file_readable(file_path));
134
+ auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write;
135
+ atomic_write_to_file("test\n", file_path, perms, std::ios::binary);
136
+ REQUIRE(file_readable(file_path));
137
+ auto stat = boost::filesystem::status(file_path);
138
+ REQUIRE(stat.permissions() == perms);
139
+ boost::filesystem::remove(file_path);
140
+ REQUIRE_FALSE(file_readable(file_path));
141
+ }
142
142
  #endif
143
+ }
144
+
145
+ TEST_CASE("file_util::read", "[utils]") {
146
+
147
+ SECTION("trying to read a nonexistent file returns the empty string"){
148
+ std::string contents;
149
+ REQUIRE(read("does_not_exist") == "");
150
+ REQUIRE_FALSE(read("does_not_exist", contents));
151
+ REQUIRE(contents.empty());
152
+ }
153
+
154
+ SECTION("it can read from a file") {
155
+ auto file_path = unique_fixture_path().string();
156
+ atomic_write_to_file("test\n", file_path);
157
+ REQUIRE(file_readable(file_path));
158
+ std::string contents;
159
+ REQUIRE(read(file_path, contents));
160
+ REQUIRE(contents == "test\n");
161
+ REQUIRE(read(file_path) == "test\n");
162
+ boost::filesystem::remove(file_path);
143
163
  }
164
+ }
144
165
 
145
- TEST_CASE("file_util::read", "[utils]") {
146
-
147
- SECTION("trying to read a nonexistent file returns the empty string"){
148
- std::string contents;
149
- REQUIRE(read("does_not_exist") == "");
150
- REQUIRE_FALSE(read("does_not_exist", contents));
151
- REQUIRE(contents.empty());
152
- }
153
-
154
- SECTION("it can read from a file") {
155
- auto file_path = unique_fixture_path().string();
156
- atomic_write_to_file("test\n", file_path);
157
- REQUIRE(file_readable(file_path));
158
- std::string contents;
159
- REQUIRE(read(file_path, contents));
160
- REQUIRE(contents == "test\n");
161
- REQUIRE(read(file_path) == "test\n");
162
- boost::filesystem::remove(file_path);
163
- }
164
- }
165
-
166
- TEST_CASE("file_util::each_line", "[utils]") {
167
-
168
- SECTION("trying to read a nonexistent file returns false") {
169
- REQUIRE_FALSE(each_line("does_not_exist", [](std::string &line) {
170
- FAIL("should not be called");
171
- return true;
172
- }));
173
- }
174
-
175
- SECTION("an action is performed on each line of a file") {
176
- temp_file file("test1\ntest2\ntest3\n");
177
- int i = 0;
178
- REQUIRE(each_line(file.get_file_name(), [&i](std::string const &line) {
179
- i++;
180
- return line == ("test" + std::to_string(i));
181
- }));
182
- REQUIRE(i == 3);
183
- }
184
-
185
- SECTION("a callback that returns false stops at the first line"){
186
- temp_file file("test1\ntest2\ntest3\n");
187
- std::vector<std::string> lines;
188
- REQUIRE(each_line(file.get_file_name(), [&](std::string& line) {
189
- lines.emplace_back(move(line));
190
- return false;
191
- }));
192
- REQUIRE(lines.size() == 1u);
193
- REQUIRE(lines[0] == "test1");
194
- }
195
- }
196
-
197
- }} // namespace leatherman::file_util
166
+ TEST_CASE("file_util::each_line", "[utils]") {
167
+
168
+ SECTION("trying to read a nonexistent file returns false") {
169
+ REQUIRE_FALSE(each_line("does_not_exist", [](std::string &line) {
170
+ FAIL("should not be called");
171
+ return true;
172
+ }));
173
+ }
174
+
175
+ SECTION("an action is performed on each line of a file") {
176
+ temp_file file("test1\ntest2\ntest3\n");
177
+ int i = 0;
178
+ REQUIRE(each_line(file.get_file_name(), [&i](std::string const &line) {
179
+ i++;
180
+ return line == ("test" + std::to_string(i));
181
+ }));
182
+ REQUIRE(i == 3);
183
+ }
184
+
185
+ SECTION("a callback that returns false stops at the first line"){
186
+ temp_file file("test1\ntest2\ntest3\n");
187
+ std::vector<std::string> lines;
188
+ REQUIRE(each_line(file.get_file_name(), [&](std::string& line) {
189
+ lines.emplace_back(move(line));
190
+ return false;
191
+ }));
192
+ REQUIRE(lines.size() == 1u);
193
+ REQUIRE(lines[0] == "test1");
194
+ }
195
+ }