cell_test_suite.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. // Copyright (c) 2014-2021 Thomas Fussell
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE
  20. //
  21. // @license: http://www.opensource.org/licenses/mit-license.php
  22. // @author: see AUTHORS file
  23. #include <sstream>
  24. #include <helpers/assertions.hpp>
  25. #include <helpers/test_suite.hpp>
  26. #include <xlnt/cell/cell.hpp>
  27. #include <xlnt/cell/comment.hpp>
  28. #include <xlnt/cell/hyperlink.hpp>
  29. #include <xlnt/styles/alignment.hpp>
  30. #include <xlnt/styles/border.hpp>
  31. #include <xlnt/styles/fill.hpp>
  32. #include <xlnt/styles/format.hpp>
  33. #include <xlnt/styles/number_format.hpp>
  34. #include <xlnt/styles/protection.hpp>
  35. #include <xlnt/styles/style.hpp>
  36. #include <xlnt/utils/date.hpp>
  37. #include <xlnt/utils/datetime.hpp>
  38. #include <xlnt/utils/time.hpp>
  39. #include <xlnt/utils/timedelta.hpp>
  40. #include <xlnt/workbook/workbook.hpp>
  41. #include <xlnt/worksheet/range.hpp>
  42. #include <xlnt/worksheet/worksheet.hpp>
  43. class cell_test_suite : public test_suite
  44. {
  45. public:
  46. cell_test_suite()
  47. {
  48. register_test(test_infer_numeric);
  49. register_test(test_constructor);
  50. register_test(test_null);
  51. register_test(test_string);
  52. register_test(test_formula1);
  53. register_test(test_formula2);
  54. register_test(test_formula3);
  55. register_test(test_not_formula);
  56. register_test(test_boolean);
  57. register_test(test_error_codes);
  58. register_test(test_insert_datetime);
  59. register_test(test_insert_date);
  60. register_test(test_insert_time);
  61. register_test(test_cell_formatted_as_date1);
  62. register_test(test_cell_formatted_as_date2);
  63. register_test(test_cell_formatted_as_date3);
  64. register_test(test_illegal_characters);
  65. register_test(test_timedelta);
  66. register_test(test_cell_offset);
  67. register_test(test_font);
  68. register_test(test_fill);
  69. register_test(test_border);
  70. register_test(test_number_format);
  71. register_test(test_alignment);
  72. register_test(test_protection);
  73. register_test(test_style);
  74. register_test(test_print);
  75. register_test(test_values);
  76. register_test(test_reference);
  77. register_test(test_anchor);
  78. register_test(test_hyperlink);
  79. register_test(test_comment);
  80. register_test(test_copy_and_compare);
  81. register_test(test_cell_phonetic_properties);
  82. }
  83. private:
  84. void test_infer_numeric()
  85. {
  86. xlnt::workbook wb;
  87. auto ws = wb.active_sheet();
  88. auto cell = ws.cell("A1");
  89. cell.value("4.2", true);
  90. xlnt_assert_delta(cell.value<double>(), 4.2, 1E-9);
  91. cell.value("-42.000", true);
  92. xlnt_assert(cell.value<int>() == -42);
  93. cell.value("0", true);
  94. xlnt_assert(cell.value<int>() == 0);
  95. cell.value("0.9999", true);
  96. xlnt_assert(cell.value<double>() == 0.9999);
  97. cell.value("99E-02", true);
  98. xlnt_assert(cell.value<double>() == 0.99);
  99. cell.value("4", true);
  100. xlnt_assert(cell.value<int>() == 4);
  101. cell.value("-1E3", true);
  102. xlnt_assert(cell.value<int>() == -1000);
  103. cell.value("2e+2", true);
  104. xlnt_assert(cell.value<int>() == 200);
  105. cell.value("3.1%", true);
  106. xlnt_assert_delta(cell.value<double>(), 0.031, 1E-9);
  107. cell.value("03:40:16", true);
  108. xlnt_assert(cell.value<xlnt::time>() == xlnt::time(3, 40, 16));
  109. cell.value("03:", true);
  110. xlnt_assert_equals(cell.value<std::string>(), "03:");
  111. cell.value("03:40", true);
  112. xlnt_assert(cell.value<xlnt::time>() == xlnt::time(3, 40));
  113. cell.value("30:33.865633336", true);
  114. xlnt_assert(cell.value<xlnt::time>() == xlnt::time(0, 30, 33, 865633));
  115. }
  116. void test_constructor()
  117. {
  118. xlnt::workbook wb;
  119. auto ws = wb.active_sheet();
  120. auto cell = ws.cell(xlnt::cell_reference("A", 1));
  121. xlnt_assert(cell.data_type() == xlnt::cell::type::empty);
  122. xlnt_assert(cell.column() == "A");
  123. xlnt_assert(cell.column_index() == 1);
  124. xlnt_assert(cell.row() == 1);
  125. xlnt_assert(cell.reference() == "A1");
  126. xlnt_assert(!cell.has_value());
  127. }
  128. void test_null()
  129. {
  130. xlnt::workbook wb;
  131. const auto datatypes =
  132. {
  133. xlnt::cell::type::empty,
  134. xlnt::cell::type::boolean,
  135. xlnt::cell::type::error,
  136. xlnt::cell::type::formula_string,
  137. xlnt::cell::type::number,
  138. xlnt::cell::type::shared_string};
  139. for (const auto &datatype : datatypes)
  140. {
  141. auto ws = wb.active_sheet();
  142. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  143. cell.data_type(datatype);
  144. xlnt_assert(cell.data_type() == datatype);
  145. cell.clear_value();
  146. xlnt_assert(cell.data_type() == xlnt::cell::type::empty);
  147. }
  148. }
  149. void test_string()
  150. {
  151. xlnt::workbook wb;
  152. auto ws = wb.active_sheet();
  153. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  154. cell.value("hello");
  155. xlnt_assert(cell.data_type() == xlnt::cell::type::shared_string);
  156. cell.value(".");
  157. xlnt_assert(cell.data_type() == xlnt::cell::type::shared_string);
  158. cell.value("0800");
  159. xlnt_assert(cell.data_type() == xlnt::cell::type::shared_string);
  160. }
  161. void test_formula1()
  162. {
  163. xlnt::workbook wb;
  164. auto ws = wb.active_sheet();
  165. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  166. cell.value("=42", true);
  167. //xlnt_assert(cell.data_type() == xlnt::cell::type::number);
  168. xlnt_assert(cell.has_formula());
  169. }
  170. void test_formula2()
  171. {
  172. xlnt::workbook wb;
  173. auto ws = wb.active_sheet();
  174. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  175. cell.value("=if(A1<4;-1;1)", true);
  176. //xlnt_assert(cell.data_type() == xlnt::cell::type::number);
  177. xlnt_assert(cell.has_formula());
  178. }
  179. void test_formula3()
  180. {
  181. xlnt::workbook wb;
  182. auto ws = wb.active_sheet();
  183. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  184. xlnt_assert(!cell.has_formula());
  185. xlnt_assert_throws_nothing(cell.formula(""));
  186. xlnt_assert(!cell.has_formula());
  187. cell.formula("=42");
  188. xlnt_assert(cell.has_formula());
  189. xlnt_assert_equals(cell.formula(), "42");
  190. cell.clear_formula();
  191. xlnt_assert(!cell.has_formula());
  192. }
  193. void test_not_formula()
  194. {
  195. xlnt::workbook wb;
  196. auto ws = wb.active_sheet();
  197. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  198. cell.value("=", true);
  199. xlnt_assert(cell.data_type() == xlnt::cell::type::shared_string);
  200. xlnt_assert(cell.value<std::string>() == "=");
  201. xlnt_assert(!cell.has_formula());
  202. }
  203. void test_boolean()
  204. {
  205. xlnt::workbook wb;
  206. auto ws = wb.active_sheet();
  207. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  208. for (auto value : {true, false})
  209. {
  210. cell.value(value);
  211. xlnt_assert(cell.data_type() == xlnt::cell::type::boolean);
  212. }
  213. }
  214. void test_error_codes()
  215. {
  216. xlnt::workbook wb;
  217. auto ws = wb.active_sheet();
  218. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  219. // error string can't be empty
  220. xlnt_assert_throws(cell.error(""), xlnt::exception);
  221. // error string has to have a leading '#'
  222. xlnt_assert_throws(cell.error("not an error"), xlnt::exception);
  223. for (auto error_code : xlnt::cell::error_codes())
  224. {
  225. // error type from the string format
  226. cell.value(error_code.first, true);
  227. xlnt_assert(cell.data_type() == xlnt::cell::type::error);
  228. std::string error;
  229. xlnt_assert_throws_nothing(error = cell.error());
  230. xlnt_assert_equals(error, error_code.first);
  231. // clearing the value clears the error state
  232. cell.clear_value();
  233. xlnt_assert_throws(cell.error(), xlnt::exception);
  234. // can explicitly set the error
  235. xlnt_assert_throws_nothing(cell.error(error_code.first));
  236. std::string error2;
  237. xlnt_assert_throws_nothing(error2 = cell.error());
  238. xlnt_assert_equals(error2, error_code.first);
  239. }
  240. }
  241. void test_insert_datetime()
  242. {
  243. xlnt::workbook wb;
  244. auto ws = wb.active_sheet();
  245. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  246. cell.value(xlnt::datetime(2010, 7, 13, 6, 37, 41));
  247. xlnt_assert(cell.data_type() == xlnt::cell::type::number);
  248. xlnt_assert_delta(cell.value<double>(), 40372.27616898148, 1E-9);
  249. xlnt_assert(cell.is_date());
  250. xlnt_assert(cell.number_format().format_string() == "yyyy-mm-dd h:mm:ss");
  251. }
  252. void test_insert_date()
  253. {
  254. xlnt::workbook wb;
  255. auto ws = wb.active_sheet();
  256. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  257. cell.value(xlnt::date(2010, 7, 13));
  258. xlnt_assert(cell.data_type() == xlnt::cell::type::number);
  259. xlnt_assert(cell.value<double>() == 40372.0);
  260. xlnt_assert(cell.is_date());
  261. xlnt_assert(cell.number_format().format_string() == "yyyy-mm-dd");
  262. }
  263. void test_insert_time()
  264. {
  265. xlnt::workbook wb;
  266. auto ws = wb.active_sheet();
  267. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  268. cell.value(xlnt::time(1, 3));
  269. xlnt_assert(cell.data_type() == xlnt::cell::type::number);
  270. xlnt_assert_delta(cell.value<double>(), 0.04375, 1E-9);
  271. xlnt_assert(cell.is_date());
  272. xlnt_assert(cell.number_format().format_string() == "h:mm:ss");
  273. }
  274. void test_cell_formatted_as_date1()
  275. {
  276. xlnt::workbook wb;
  277. auto ws = wb.active_sheet();
  278. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  279. cell.value(xlnt::datetime::today());
  280. cell.clear_value();
  281. xlnt_assert(!cell.is_date()); // disagree with openpyxl
  282. xlnt_assert(!cell.has_value());
  283. }
  284. void test_cell_formatted_as_date2()
  285. {
  286. xlnt::workbook wb;
  287. auto ws = wb.active_sheet();
  288. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  289. cell.value(xlnt::datetime::today());
  290. cell.value("testme");
  291. xlnt_assert(!cell.is_date());
  292. xlnt_assert(cell.value<std::string>() == "testme");
  293. }
  294. void test_cell_formatted_as_date3()
  295. {
  296. xlnt::workbook wb;
  297. auto ws = wb.active_sheet();
  298. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  299. cell.value(xlnt::datetime::today());
  300. cell.value(true);
  301. xlnt_assert(!cell.is_date());
  302. xlnt_assert(cell.value<bool>() == true);
  303. }
  304. void test_illegal_characters()
  305. {
  306. xlnt::workbook wb;
  307. auto ws = wb.active_sheet();
  308. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  309. // The bytes 0x00 through 0x1F inclusive must be manually escaped in values.
  310. auto illegal_chrs = {0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18,
  311. 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
  312. for (auto i : illegal_chrs)
  313. {
  314. std::string str(1, i);
  315. xlnt_assert_throws(cell.value(str), xlnt::illegal_character);
  316. }
  317. cell.value(std::string(1, 33));
  318. cell.value(std::string(1, 9)); // Tab
  319. cell.value(std::string(1, 10)); // Newline
  320. cell.value(std::string(1, 13)); // Carriage return
  321. cell.value(" Leading and trailing spaces are legal ");
  322. }
  323. // void test_time_regex() {}
  324. void test_timedelta()
  325. {
  326. xlnt::workbook wb;
  327. auto ws = wb.active_sheet();
  328. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  329. cell.value(xlnt::timedelta(1, 3, 0, 0, 0));
  330. xlnt_assert(cell.value<double>() == 1.125);
  331. xlnt_assert(cell.data_type() == xlnt::cell::type::number);
  332. xlnt_assert(!cell.is_date());
  333. xlnt_assert(cell.number_format().format_string() == "[hh]:mm:ss");
  334. }
  335. void test_cell_offset()
  336. {
  337. xlnt::workbook wb;
  338. auto ws = wb.active_sheet();
  339. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  340. xlnt_assert(cell.offset(1, 2).reference() == "B3");
  341. }
  342. void test_font()
  343. {
  344. xlnt::workbook wb;
  345. auto ws = wb.active_sheet();
  346. auto cell = ws.cell("A1");
  347. auto font = xlnt::font().bold(true);
  348. cell.font(font);
  349. xlnt_assert(cell.has_format());
  350. xlnt_assert(cell.format().font_applied());
  351. xlnt_assert_equals(cell.font(), font);
  352. }
  353. void test_fill()
  354. {
  355. xlnt::workbook wb;
  356. auto ws = wb.active_sheet();
  357. auto cell = ws.cell("A1");
  358. xlnt::fill fill(xlnt::pattern_fill()
  359. .type(xlnt::pattern_fill_type::solid)
  360. .foreground(xlnt::color::red()));
  361. cell.fill(fill);
  362. xlnt_assert(cell.has_format());
  363. xlnt_assert(cell.format().fill_applied());
  364. xlnt_assert_equals(cell.fill(), fill);
  365. }
  366. void test_border()
  367. {
  368. xlnt::workbook wb;
  369. auto ws = wb.active_sheet();
  370. auto cell = ws.cell("A1");
  371. xlnt::border border;
  372. cell.border(border);
  373. xlnt_assert(cell.has_format());
  374. xlnt_assert(cell.format().border_applied());
  375. xlnt_assert_equals(cell.border(), border);
  376. }
  377. void test_number_format()
  378. {
  379. xlnt::workbook wb;
  380. auto ws = wb.active_sheet();
  381. auto cell = ws.cell("A1");
  382. xlnt::number_format format("dd--hh--mm");
  383. cell.number_format(format);
  384. xlnt_assert(cell.has_format());
  385. xlnt_assert(cell.format().number_format_applied());
  386. xlnt_assert_equals(cell.number_format().format_string(), "dd--hh--mm");
  387. }
  388. void test_alignment()
  389. {
  390. xlnt::workbook wb;
  391. auto ws = wb.active_sheet();
  392. auto cell = ws.cell("A1");
  393. xlnt::alignment align;
  394. align.wrap(true);
  395. cell.alignment(align);
  396. xlnt_assert(cell.has_format());
  397. xlnt_assert(cell.format().alignment_applied());
  398. xlnt_assert_equals(cell.alignment(), align);
  399. }
  400. void test_protection()
  401. {
  402. xlnt::workbook wb;
  403. auto ws = wb.active_sheet();
  404. auto cell = ws.cell("A1");
  405. xlnt_assert(!cell.has_format());
  406. auto protection = xlnt::protection().locked(false).hidden(true);
  407. cell.protection(protection);
  408. xlnt_assert(cell.has_format());
  409. xlnt_assert(cell.format().protection_applied());
  410. xlnt_assert_equals(cell.protection(), protection);
  411. xlnt_assert(cell.has_format());
  412. cell.clear_format();
  413. xlnt_assert(!cell.has_format());
  414. }
  415. void test_style()
  416. {
  417. xlnt::workbook wb;
  418. auto ws = wb.active_sheet();
  419. auto cell = ws.cell("A1");
  420. xlnt_assert(!cell.has_style());
  421. auto test_style = wb.create_style("test_style");
  422. test_style.number_format(xlnt::number_format::date_ddmmyyyy(), true);
  423. cell.style(test_style);
  424. xlnt_assert(cell.has_style());
  425. xlnt_assert_equals(cell.style().number_format(), xlnt::number_format::date_ddmmyyyy());
  426. xlnt_assert_equals(cell.style(), test_style);
  427. auto other_style = wb.create_style("other_style");
  428. other_style.number_format(xlnt::number_format::date_time2(), true);
  429. cell.style("other_style");
  430. xlnt_assert_equals(cell.style().number_format(), xlnt::number_format::date_time2());
  431. xlnt_assert_equals(cell.style(), other_style);
  432. auto last_style = wb.create_style("last_style");
  433. last_style.number_format(xlnt::number_format::percentage(), true);
  434. cell.style(last_style);
  435. xlnt_assert_equals(cell.style().number_format(), xlnt::number_format::percentage());
  436. xlnt_assert_equals(cell.style(), last_style);
  437. xlnt_assert_throws(cell.style("doesn't exist"), xlnt::key_not_found);
  438. cell.clear_style();
  439. xlnt_assert(!cell.has_style());
  440. xlnt_assert_throws(cell.style(), xlnt::invalid_attribute);
  441. }
  442. void test_print()
  443. {
  444. xlnt::workbook wb;
  445. auto ws = wb.active_sheet();
  446. {
  447. auto cell = ws.cell("A1");
  448. std::stringstream ss;
  449. ss << cell;
  450. auto stream_string = ss.str();
  451. xlnt_assert_equals(cell.to_string(), stream_string);
  452. xlnt_assert_equals(stream_string, "");
  453. }
  454. {
  455. auto cell = ws.cell("A2");
  456. cell.value(false);
  457. std::stringstream ss;
  458. ss << cell;
  459. auto stream_string = ss.str();
  460. xlnt_assert_equals(cell.to_string(), stream_string);
  461. xlnt_assert_equals(stream_string, "FALSE");
  462. }
  463. {
  464. auto cell = ws.cell("A3");
  465. cell.value(true);
  466. std::stringstream ss;
  467. ss << cell;
  468. auto stream_string = ss.str();
  469. xlnt_assert_equals(cell.to_string(), stream_string);
  470. xlnt_assert_equals(stream_string, "TRUE");
  471. }
  472. {
  473. auto cell = ws.cell("A4");
  474. cell.value(1.234);
  475. std::stringstream ss;
  476. ss << cell;
  477. auto stream_string = ss.str();
  478. xlnt_assert_equals(cell.to_string(), stream_string);
  479. xlnt_assert_equals(stream_string, "1.234");
  480. }
  481. {
  482. auto cell = ws.cell("A5");
  483. cell.error("#REF");
  484. std::stringstream ss;
  485. ss << cell;
  486. auto stream_string = ss.str();
  487. xlnt_assert_equals(cell.to_string(), stream_string);
  488. xlnt_assert_equals(stream_string, "#REF");
  489. }
  490. {
  491. auto cell = ws.cell("A6");
  492. cell.value("test");
  493. std::stringstream ss;
  494. ss << cell;
  495. auto stream_string = ss.str();
  496. xlnt_assert_equals(cell.to_string(), stream_string);
  497. xlnt_assert_equals(stream_string, "test");
  498. }
  499. }
  500. void test_values()
  501. {
  502. xlnt::workbook wb;
  503. auto ws = wb.active_sheet();
  504. auto cell = ws.cell("A1");
  505. cell.value(static_cast<int>(4));
  506. xlnt_assert_equals(cell.value<int>(), 4);
  507. cell.value(static_cast<unsigned int>(3));
  508. xlnt_assert_equals(cell.value<unsigned>(), 3);
  509. cell.value(static_cast<unsigned long long>(4));
  510. xlnt_assert_equals(cell.value<unsigned long long>(), 4);
  511. cell.value(static_cast<long long int>(3));
  512. xlnt_assert_equals(cell.value<long long int>(), 3);
  513. cell.value(static_cast<float>(3.14));
  514. xlnt_assert_delta(cell.value<float>(), 3.14, 0.001);
  515. cell.value(static_cast<double>(3.141592));
  516. xlnt_assert_equals(cell.value<double>(), 3.141592);
  517. auto cell2 = ws.cell("A2");
  518. cell2.value(std::string(100000, 'a'));
  519. cell.value(cell2);
  520. xlnt_assert_equals(cell.value<std::string>(), std::string(32767, 'a'));
  521. }
  522. void test_reference()
  523. {
  524. xlnt::cell_reference_hash hash;
  525. xlnt_assert_differs(hash(xlnt::cell_reference("A2")), hash(xlnt::cell_reference(1, 1)));
  526. xlnt_assert_equals(hash(xlnt::cell_reference("A2")), hash(xlnt::cell_reference(1, 2)));
  527. xlnt_assert_equals((xlnt::cell_reference("A1"), xlnt::cell_reference("B2")), xlnt::range_reference("A1:B2"));
  528. xlnt_assert_throws(xlnt::cell_reference("A1&"), xlnt::invalid_cell_reference);
  529. xlnt_assert_throws(xlnt::cell_reference("A"), xlnt::invalid_cell_reference);
  530. auto ref = xlnt::cell_reference("$B$7");
  531. xlnt_assert_equals(ref.row_absolute(), true);
  532. xlnt_assert_equals(ref.column_absolute(), true);
  533. ref = xlnt::cell_reference("$B7");
  534. xlnt_assert_equals(ref.row_absolute(), false);
  535. xlnt_assert_equals(ref.column_absolute(), true);
  536. ref = xlnt::cell_reference("B$7");
  537. xlnt_assert_equals(ref.row_absolute(), true);
  538. xlnt_assert_equals(ref.column_absolute(), false);
  539. xlnt_assert(xlnt::cell_reference("A1") == "A1");
  540. xlnt_assert(xlnt::cell_reference("A1") != "A2");
  541. }
  542. void test_anchor()
  543. {
  544. xlnt::workbook wb;
  545. auto cell = wb.active_sheet().cell("A1");
  546. auto anchor = cell.anchor();
  547. xlnt_assert_equals(anchor.first, 0);
  548. xlnt_assert_equals(anchor.second, 0);
  549. }
  550. void test_hyperlink()
  551. {
  552. xlnt::workbook wb;
  553. auto cell = wb.active_sheet().cell("A1");
  554. xlnt_assert(!cell.has_hyperlink());
  555. xlnt_assert_throws(cell.hyperlink(), xlnt::invalid_attribute);
  556. xlnt_assert_throws(cell.hyperlink(""), xlnt::invalid_parameter);
  557. // link without optional display
  558. const std::string link1("http://example.com");
  559. cell.hyperlink(link1);
  560. xlnt_assert(cell.has_hyperlink());
  561. xlnt_assert(cell.hyperlink().external());
  562. xlnt_assert_equals(cell.hyperlink().url(), link1);
  563. xlnt_assert_equals(cell.hyperlink().relationship().target().to_string(), link1);
  564. xlnt_assert_equals(cell.hyperlink().display(), link1);
  565. cell.clear_value();
  566. // link with display
  567. const std::string link2("http://example2.com");
  568. const std::string display_txt("notaurl");
  569. cell.hyperlink(link2, display_txt);
  570. xlnt_assert(cell.has_hyperlink());
  571. xlnt_assert(cell.hyperlink().external());
  572. xlnt_assert_equals(cell.hyperlink().url(), link2);
  573. xlnt_assert_equals(cell.hyperlink().relationship().target().to_string(), link2);
  574. xlnt_assert_equals(cell.hyperlink().display(), display_txt);
  575. // relative (local) url
  576. const std::string local("../test_local");
  577. cell.hyperlink(local);
  578. xlnt_assert(cell.has_hyperlink());
  579. xlnt_assert(cell.hyperlink().external());
  580. xlnt_assert_equals(cell.hyperlink().url(), local);
  581. xlnt_assert_equals(cell.hyperlink().relationship().target().to_string(), local);
  582. // value
  583. int cell_test_val = 123;
  584. cell.value(cell_test_val);
  585. std::string cell_value_str = std::to_string(cell_test_val);
  586. cell.hyperlink(link2, display_txt);
  587. xlnt_assert_equals(cell.value<int>(), 123);
  588. xlnt_assert_equals(cell.hyperlink().display(), cell_value_str); // display text ignored
  589. cell.clear_value();
  590. // cell overload without display
  591. const std::string cell_target_str("A2");
  592. auto cell_target = wb.active_sheet().cell(cell_target_str);
  593. std::string link3 = wb.active_sheet().title() + '!' + cell_target_str; // Sheet1!A2
  594. cell.hyperlink(cell_target);
  595. xlnt_assert(cell.has_hyperlink());
  596. xlnt_assert(!cell.hyperlink().external());
  597. xlnt_assert_equals(cell.hyperlink().target_range(), link3);
  598. xlnt_assert_equals(cell.hyperlink().display(), link3);
  599. cell.clear_value();
  600. // cell overload with display
  601. cell.hyperlink(cell_target, display_txt);
  602. xlnt_assert(cell.has_hyperlink());
  603. xlnt_assert(!cell.hyperlink().external());
  604. xlnt_assert_equals(cell.hyperlink().target_range(), link3);
  605. xlnt_assert_equals(cell.hyperlink().display(), display_txt);
  606. // value
  607. cell.value(cell_test_val);
  608. cell.hyperlink(cell_target, display_txt);
  609. xlnt_assert_equals(cell.value<int>(), 123);
  610. xlnt_assert_equals(cell.hyperlink().display(), cell_value_str); // display text ignored
  611. cell.clear_value();
  612. // range overload without display
  613. const std::string range_target_str("A2:A5");
  614. xlnt::range range_target(wb.active_sheet(), xlnt::range_reference(range_target_str));
  615. std::string link4 = wb.active_sheet().title() + '!' + range_target_str; // Sheet1!A2:A5
  616. cell.hyperlink(range_target);
  617. xlnt_assert(cell.has_hyperlink());
  618. xlnt_assert(!cell.hyperlink().external());
  619. xlnt_assert_equals(cell.hyperlink().target_range(), link4);
  620. xlnt_assert_equals(cell.hyperlink().display(), link4);
  621. cell.clear_value();
  622. // range overload with display
  623. cell.hyperlink(range_target, display_txt);
  624. xlnt_assert(cell.has_hyperlink());
  625. xlnt_assert(!cell.hyperlink().external());
  626. xlnt_assert_equals(cell.hyperlink().target_range(), link4);
  627. xlnt_assert_equals(cell.hyperlink().display(), display_txt);
  628. // value
  629. cell.value(cell_test_val);
  630. cell.hyperlink(range_target, display_txt);
  631. xlnt_assert_equals(cell.value<int>(), 123);
  632. xlnt_assert_equals(cell.hyperlink().display(), cell_value_str); // display text ignored
  633. cell.clear_value();
  634. }
  635. void test_comment()
  636. {
  637. xlnt::workbook wb;
  638. auto ws = wb.active_sheet();
  639. auto cell = ws.cell("A1");
  640. xlnt_assert(!cell.has_comment());
  641. xlnt_assert_throws(cell.comment(), xlnt::exception);
  642. cell.comment(xlnt::comment("comment", "author"));
  643. xlnt_assert(cell.has_comment());
  644. xlnt_assert_equals(cell.comment(), xlnt::comment("comment", "author"));
  645. cell.clear_comment();
  646. xlnt_assert(!cell.has_comment());
  647. xlnt_assert_throws(cell.comment(), xlnt::exception);
  648. xlnt::comment comment_with_size("test comment", "author");
  649. comment_with_size.size(1000, 30);
  650. cell.comment(comment_with_size);
  651. xlnt_assert_equals(cell.comment(), comment_with_size);
  652. }
  653. void test_copy_and_compare()
  654. {
  655. xlnt::workbook wb;
  656. auto ws = wb.active_sheet();
  657. auto cell1 = ws.cell("A1");
  658. auto cell2 = ws.cell("A2");
  659. xlnt_assert_equals(cell1, cell1);
  660. xlnt_assert_equals(cell2, cell2);
  661. xlnt_assert_differs(cell1, cell2);
  662. xlnt_assert_differs(cell2, cell1);
  663. // nullptr equality
  664. xlnt_assert(nullptr == cell1);
  665. xlnt_assert(cell1 == nullptr);
  666. cell1.value("test");
  667. xlnt_assert(!(nullptr == cell1));
  668. xlnt_assert(!(cell1 == nullptr));
  669. // copy
  670. xlnt::cell cell3(cell1);
  671. xlnt_assert_equals(cell1, cell3);
  672. // assign
  673. cell3 = cell2;
  674. xlnt_assert_equals(cell2, cell3);
  675. }
  676. void test_cell_phonetic_properties()
  677. {
  678. xlnt::workbook wb;
  679. auto ws = wb.active_sheet();
  680. auto cell1 = ws.cell("A1");
  681. xlnt_assert_equals(cell1.phonetics_visible(), false);
  682. cell1.show_phonetics(true);
  683. xlnt_assert_equals(cell1.phonetics_visible(), true);
  684. cell1.show_phonetics(false);
  685. xlnt_assert_equals(cell1.phonetics_visible(), false);
  686. }
  687. };
  688. static cell_test_suite x{};