1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "contrib/libxls/sandboxed.h"
16 #include "contrib/libxls/utils/utils_libxls.h"
17 #undef FILE // TODO(cblichmann): Artifact from generated header
18
19 #include "sandboxed_api/util/path.h"
20 #include "sandboxed_api/util/status_matchers.h"
21
22 namespace {
23
24 using ::sapi::IsOk;
25 using ::testing::Not;
26
27 struct Sheet {
28 int count_row;
29 int count_col;
30 double values[4][4];
31 };
32
33 const struct TestCase {
34 std::string filename;
35 size_t sheet_count;
36 struct Sheet sheet[2];
37 } kTestData[] = {
38 {
39 .filename = "t1.xls",
40 .sheet_count = 1,
41 .sheet =
42 {
43 {.count_row = 4,
44 .count_col = 2,
45 .values =
46 {
47 {1, 2, 0, 0},
48 {3, 4, 0, 0},
49 {5, 6, 0, 0},
50 {7, 8, 0, 0},
51 }},
52 },
53 },
54 {
55 .filename = "t2.xls",
56 .sheet_count = 2,
57 .sheet =
58 {
59 {.count_row = 2,
60 .count_col = 3,
61 .values =
62 {
63 {1, 2, 3, 0},
64 {4, 5, 6, 0},
65 {0, 0, 0, 0},
66 {0, 0, 0, 0},
67 }},
68 {.count_row = 2,
69 .count_col = 2,
70 .values =
71 {
72 {9, 8, 0, 0},
73 {7, 6, 0, 0},
74 {0, 0, 0, 0},
75 {0, 0, 0, 0},
76 }},
77 },
78 },
79 };
80
81 class LibXlsBase : public testing::Test {
82 protected:
GetTestFilePath(const std::string & filename)83 std::string GetTestFilePath(const std::string& filename) {
84 return sapi::file::JoinPath(test_dir_, filename);
85 }
86
87 void SetUp() override;
88
89 const char* test_dir_;
90 };
91
92 class LibXlsTestFiles : public LibXlsBase,
93 public testing::WithParamInterface<TestCase> {};
94
SetUp()95 void LibXlsBase::SetUp() {
96 test_dir_ = getenv("TEST_FILES_DIR");
97 ASSERT_NE(test_dir_, nullptr);
98 }
99
TEST_P(LibXlsTestFiles,TestValues)100 TEST_P(LibXlsTestFiles, TestValues) {
101 const TestCase& tv = GetParam();
102 std::string test_file_path = GetTestFilePath(tv.filename);
103
104 LibxlsSapiSandbox sandbox(test_file_path);
105 SAPI_ASSERT_OK(sandbox.Init());
106
107 SAPI_ASSERT_OK_AND_ASSIGN(LibXlsWorkbook wb,
108 LibXlsWorkbook::Open(&sandbox, test_file_path));
109 ASSERT_EQ(wb.GetSheetCount(), tv.sheet_count);
110
111 for (int i = 0; i < tv.sheet_count; ++i) {
112 SAPI_ASSERT_OK_AND_ASSIGN(LibXlsSheet sheet, wb.OpenSheet(i));
113 ASSERT_EQ(sheet.GetRowCount(), tv.sheet[i].count_row);
114 ASSERT_EQ(sheet.GetColCount(), tv.sheet[i].count_col);
115 for (size_t row = 0; row < sheet.GetRowCount(); ++row) {
116 for (size_t col = 0; col < sheet.GetColCount(); ++col) {
117 SAPI_ASSERT_OK_AND_ASSIGN(LibXlsCell cell, sheet.GetCell(row, col));
118 ASSERT_EQ(cell.type, XLS_RECORD_NUMBER);
119 ASSERT_EQ(std::get<double>(cell.value), tv.sheet[i].values[row][col]);
120 }
121 }
122 }
123 }
124
125 INSTANTIATE_TEST_SUITE_P(LibXlsBase, LibXlsTestFiles,
126 testing::ValuesIn(kTestData));
127
TEST_F(LibXlsBase,TestFormula)128 TEST_F(LibXlsBase, TestFormula) {
129 std::string test_file_path = GetTestFilePath("t3.xls");
130
131 LibxlsSapiSandbox sandbox(test_file_path);
132 SAPI_ASSERT_OK(sandbox.Init());
133
134 SAPI_ASSERT_OK_AND_ASSIGN(LibXlsWorkbook wb,
135 LibXlsWorkbook::Open(&sandbox, test_file_path));
136
137 SAPI_ASSERT_OK_AND_ASSIGN(LibXlsSheet sheet, wb.OpenSheet(0));
138 SAPI_ASSERT_OK_AND_ASSIGN(LibXlsCell cell, sheet.GetCell(0, 0));
139 ASSERT_EQ(cell.type, XLS_RECORD_STRING);
140 ASSERT_EQ(std::get<std::string>(cell.value), "10.000000");
141 }
142
143 } // namespace
144