fix all tests

This commit is contained in:
Thomas Fussell 2015-11-01 23:52:19 -05:00
parent fef68e460f
commit 2f8032437c
28 changed files with 186 additions and 275 deletions

3
.gitignore vendored
View File

@ -1,7 +1,6 @@
bin/ bin/
lib/ lib/
build/genie/*/ build/
build/cmake/build/
docs/_*/ docs/_*/
docs/doxyxml/ docs/doxyxml/
*.obj *.obj

View File

@ -28,5 +28,5 @@ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/../bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/../bin)
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
include(xlnt.cmake)
include(xlnt.test.cmake) include(xlnt.test.cmake)
include(xlnt.cmake)

View File

@ -1,11 +0,0 @@
ACTION=$1
if [ "$ACTION" = "clean" ]; then
rm -rf build
exit 0
fi
mkdir build
cd build
cmake ..
make

View File

@ -1,11 +0,0 @@
ACTION=$1
if [ "$ACTION" = "clean" ]; then
rm -rf build
exit 0
fi
mkdir ../build
cd ../build
cmake -G "Unix Makefiles" ../cmake
make

View File

@ -9,4 +9,3 @@ dirs = ['../bin', '../lib', '../build']
for dir in dirs: for dir in dirs:
if os.path.isdir(dir): shutil.rmtree(dir) if os.path.isdir(dir): shutil.rmtree(dir)

19
cmake/configure vendored Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
os.chdir(os.path.dirname(os.path.abspath(__file__)))
if not os.path.isdir('../build'):
os.mkdir('../build')
generator = 'Unix Makefiles'
if sys.platform == 'darwin':
generator = 'Unix Makefiles'
elif sys.platform == 'win32':
generator = 'Visual Studio 14 2015'
subprocess.call(['cmake3', '-G', generator, '../cmake'], cwd='../build')

View File

@ -5,16 +5,24 @@ include_directories(../source)
include_directories(../third-party/pugixml/src) include_directories(../third-party/pugixml/src)
include_directories(../third-party/cxxtest) include_directories(../third-party/cxxtest)
add_executable(xlnt.test ../tests/runner-autogen.cpp) FILE(GLOB TEST_HEADERS ../tests/*.hpp)
FILE(GLOB TEST_HELPERS_HEADERS ../tests/helpers/*.hpp)
FILE(GLOB TEST_HELPERS_SOURCES ../tests/helpers/*.cpp)
add_executable(xlnt.test ../tests/runner-autogen.cpp ${TEST_HEADERS} ${TEST_HELPERS_HEADERS} ${TEST_HELPERS_SOURCES})
source_group(runner FILES ../tests/runner-autogen.cpp)
source_group(tests FILES ${TEST_HEADERS})
source_group(helpers FILES ${TEST_HELPERS_HEADERS} ${TEST_HELPERS_SOURCES})
target_link_libraries(xlnt.test xlnt) target_link_libraries(xlnt.test xlnt)
add_custom_target (test-runner add_custom_target (generate-test-runner
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate-tests.sh COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate-tests.sh
COMMENT "Generating test runner tests/runner-autogen.cpp" COMMENT "Generating test runner tests/runner-autogen.cpp"
) )
add_dependencies(xlnt.test test-runner) add_dependencies(xlnt.test generate-test-runner)
add_custom_command( add_custom_command(
TARGET xlnt.test TARGET xlnt.test

View File

@ -52,9 +52,6 @@ class workbook_serializer
xml_document write_properties_app() const; xml_document write_properties_app() const;
xml_document write_properties_core() const; xml_document write_properties_core() const;
std::vector<string_pair> read_sheets();
std::vector<string_pair> detect_worksheets();
xml_node write_named_ranges() const; xml_node write_named_ranges() const;
private: private:

View File

@ -910,6 +910,7 @@ template <>
void cell::set_value(std::string s) void cell::set_value(std::string s)
{ {
d_->set_string(s, get_parent().get_parent().get_guess_types()); d_->set_string(s, get_parent().get_parent().get_guess_types());
if(!s.empty()) get_parent().get_parent().add_shared_string(s);
} }
template <> template <>

View File

@ -44,16 +44,27 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
wb.set_guess_types(guess_types); wb.set_guess_types(guess_types);
wb.set_data_only(data_only); wb.set_data_only(data_only);
if(!archive.has_file(xlnt::constants::ArcContentTypes))
{
throw xlnt::invalid_file_exception("missing [Content Types].xml");
}
xlnt::manifest_serializer ms(wb.get_manifest()); xlnt::manifest_serializer ms(wb.get_manifest());
ms.read_manifest(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcContentTypes))); ms.read_manifest(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcContentTypes)));
if (ms.determine_document_type() != "excel") if (ms.determine_document_type() != "excel")
{ {
throw xlnt::invalid_file_exception(""); throw xlnt::invalid_file_exception("package is not an OOXML SpreadsheetML");
} }
wb.clear(); wb.clear();
if(archive.has_file(xlnt::constants::ArcCore))
{
xlnt::workbook_serializer workbook_serializer_(wb);
workbook_serializer_.read_properties_core(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcCore)));
}
auto workbook_relationships = auto workbook_relationships =
xlnt::relationship_serializer::read_relationships(archive, xlnt::constants::ArcWorkbook); xlnt::relationship_serializer::read_relationships(archive, xlnt::constants::ArcWorkbook);
@ -72,6 +83,8 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
? xlnt::calendar::mac_1904 ? xlnt::calendar::mac_1904
: xlnt::calendar::windows_1900; : xlnt::calendar::windows_1900;
if(archive.has_file(xlnt::constants::ArcSharedString))
{
xlnt::shared_strings_serializer shared_strings_serializer_; xlnt::shared_strings_serializer shared_strings_serializer_;
std::vector<std::string> shared_strings; std::vector<std::string> shared_strings;
shared_strings_serializer_.read_shared_strings( shared_strings_serializer_.read_shared_strings(
@ -81,6 +94,7 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
{ {
wb.add_shared_string(shared_string); wb.add_shared_string(shared_string);
} }
}
xlnt::style_serializer style_reader_(wb); xlnt::style_serializer style_reader_(wb);
style_reader_.read_stylesheet(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcStyles))); style_reader_.read_stylesheet(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcStyles)));
@ -91,7 +105,12 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
{ {
auto rel = wb.get_relationship(sheet_node.get_attribute("r:id")); auto rel = wb.get_relationship(sheet_node.get_attribute("r:id"));
auto ws = wb.create_sheet(sheet_node.get_attribute("name"), rel); auto ws = wb.create_sheet(sheet_node.get_attribute("name"), rel);
auto ws_filename = "xl/" + rel.get_target_uri(); //TODO: this is really bad
auto ws_filename = (rel.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + rel.get_target_uri();
auto sheet_type = wb.get_manifest().get_override_type(ws_filename);
if(sheet_type != "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml") continue;
xlnt::worksheet_serializer worksheet_serializer(ws); xlnt::worksheet_serializer worksheet_serializer(ws);
worksheet_serializer.read_worksheet(xlnt::xml_serializer::deserialize(archive.read(ws_filename))); worksheet_serializer.read_worksheet(xlnt::xml_serializer::deserialize(archive.read(ws_filename)));
@ -123,7 +142,12 @@ std::string excel_serializer::repair_central_directory(const std::string &origin
bool excel_serializer::load_stream_workbook(std::istream &stream, bool guess_types, bool data_only) bool excel_serializer::load_stream_workbook(std::istream &stream, bool guess_types, bool data_only)
{ {
std::vector<std::uint8_t> bytes((std::istream_iterator<char>(stream)), std::istream_iterator<char>()); std::vector<std::uint8_t> bytes;
while (stream.good())
{
bytes.push_back(stream.get());
}
return load_virtual_workbook(bytes, guess_types, data_only); return load_virtual_workbook(bytes, guess_types, data_only);
} }
@ -196,7 +220,7 @@ void excel_serializer::write_worksheets()
workbook::index_from_ws_filename(relationship.get_target_uri()) == index) workbook::index_from_ws_filename(relationship.get_target_uri()) == index)
{ {
worksheet_serializer serializer_(ws); worksheet_serializer serializer_(ws);
std::string ws_filename = "xl/" + relationship.get_target_uri(); std::string ws_filename = (relationship.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + relationship.get_target_uri();
archive_.writestr(ws_filename, serializer_.write_worksheet().to_string()); archive_.writestr(ws_filename, serializer_.write_worksheet().to_string());
break; break;
} }

View File

@ -59,47 +59,10 @@ workbook_serializer::workbook_serializer(workbook &wb) : workbook_(wb)
{ {
} }
std::vector<workbook_serializer::string_pair> workbook_serializer::read_sheets()
{
/*
std::string ns;
for(auto child : doc.children())
{
std::string name = child.name();
if(name.find(':') != std::string::npos)
{
auto colon_index = name.find(':');
ns = name.substr(0, colon_index);
break;
}
}
auto with_ns = [&](const std::string &base) { return ns.empty() ? base : ns + ":" + base; };
auto root_node = doc.get_child(with_ns("workbook"));
auto sheets_node = root_node.get_child(with_ns("sheets"));
*/
std::vector<string_pair> sheets;
/*
// store temp because pugixml iteration uses the internal char array multiple times
auto sheet_element_name = with_ns("sheet");
for(auto sheet_node : sheets_node.children(sheet_element_name))
{
std::string id = sheet_node.attribute("r:id").as_string();
std::string name = sheet_node.attribute("name").as_string();
sheets.push_back(std::make_pair(id, name));
}
*/
return sheets;
}
void workbook_serializer::read_properties_core(const xml_document &xml) void workbook_serializer::read_properties_core(const xml_document &xml)
{ {
auto &props = workbook_.get_properties(); auto &props = workbook_.get_properties();
auto root_node = xml.get_child("dc:coreProperties"); auto root_node = xml.get_child("cp:coreProperties");
props.excel_base_date = calendar::windows_1900; props.excel_base_date = calendar::windows_1900;
@ -123,45 +86,6 @@ void workbook_serializer::read_properties_core(const xml_document &xml)
} }
} }
/// <summary>
/// Return a list of worksheets.
/// content types has a list of paths but no titles
/// workbook has a list of titles and relIds but no paths
/// workbook_rels has a list of relIds and paths but no titles
/// </summary>
std::vector<workbook_serializer::string_pair> workbook_serializer::detect_worksheets()
{
static const std::string ValidWorksheet =
"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
std::vector<std::string> valid_sheets;
for (const auto &content_type : workbook_.get_manifest().get_override_types())
{
if (content_type.get_content_type() == ValidWorksheet)
{
valid_sheets.push_back(content_type.get_part_name());
}
}
auto &workbook_relationships = workbook_.get_relationships();
std::vector<std::pair<std::string, std::string>> result;
for (const auto &ws : read_sheets())
{
auto rel = *std::find_if(workbook_relationships.begin(), workbook_relationships.end(),
[&](const relationship &r) { return r.get_id() == ws.first; });
auto target = rel.get_target_uri();
if (std::find(valid_sheets.begin(), valid_sheets.end(), "/" + target) != valid_sheets.end())
{
result.push_back({ target, ws.second });
}
}
return result;
}
xml_document workbook_serializer::write_properties_core() const xml_document workbook_serializer::write_properties_core() const
{ {
auto &props = workbook_.get_properties(); auto &props = workbook_.get_properties();

View File

@ -189,8 +189,8 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
auto min = static_cast<column_t>(std::stoull(col_node.get_attribute("min"))); auto min = static_cast<column_t>(std::stoull(col_node.get_attribute("min")));
auto max = static_cast<column_t>(std::stoull(col_node.get_attribute("max"))); auto max = static_cast<column_t>(std::stoull(col_node.get_attribute("max")));
auto width = std::stold(col_node.get_attribute("width")); auto width = std::stold(col_node.get_attribute("width"));
auto column_style = std::stoull(col_node.get_attribute("style"));
bool custom = col_node.get_attribute("customWidth") == "1"; bool custom = col_node.get_attribute("customWidth") == "1";
auto column_style = col_node.has_attribute("style") ? std::stoull(col_node.get_attribute("style")) : 0;
for (auto column = min; column <= max; column++) for (auto column = min; column <= max; column++)
{ {
@ -217,8 +217,6 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
xml_document worksheet_serializer::write_worksheet() const xml_document worksheet_serializer::write_worksheet() const
{ {
sheet_.get_cell("A1");
xml_document xml; xml_document xml;
auto root_node = xml.add_child("worksheet"); auto root_node = xml.add_child("worksheet");
@ -228,17 +226,17 @@ xml_document worksheet_serializer::write_worksheet() const
auto sheet_pr_node = root_node.add_child("sheetPr"); auto sheet_pr_node = root_node.add_child("sheetPr");
auto outline_pr_node = sheet_pr_node.add_child("outlinePr");
outline_pr_node.add_attribute("summaryBelow", "1");
outline_pr_node.add_attribute("summaryRight", "1");
if (!sheet_.get_page_setup().is_default()) if (!sheet_.get_page_setup().is_default())
{ {
auto page_set_up_pr_node = sheet_pr_node.add_child("pageSetUpPr"); auto page_set_up_pr_node = sheet_pr_node.add_child("pageSetUpPr");
page_set_up_pr_node.add_attribute("fitToPage", sheet_.get_page_setup().fit_to_page() ? "1" : "0"); page_set_up_pr_node.add_attribute("fitToPage", sheet_.get_page_setup().fit_to_page() ? "1" : "0");
} }
auto outline_pr_node = sheet_pr_node.add_child("outlinePr");
outline_pr_node.add_attribute("summaryBelow", "1");
outline_pr_node.add_attribute("summaryRight", "1");
auto dimension_node = root_node.add_child("dimension"); auto dimension_node = root_node.add_child("dimension");
dimension_node.add_attribute("ref", sheet_.calculate_dimension().to_string()); dimension_node.add_attribute("ref", sheet_.calculate_dimension().to_string());
@ -530,12 +528,34 @@ xml_document worksheet_serializer::write_worksheet() const
auto page_margins_node = root_node.add_child("pageMargins"); auto page_margins_node = root_node.add_child("pageMargins");
page_margins_node.add_attribute("left", std::to_string(sheet_.get_page_margins().get_left())); //TODO: there must be a better way to do this
page_margins_node.add_attribute("right", std::to_string(sheet_.get_page_margins().get_right())); auto remove_trailing_zeros = [](const std::string &n)
page_margins_node.add_attribute("top", std::to_string(sheet_.get_page_margins().get_top())); {
page_margins_node.add_attribute("bottom", std::to_string(sheet_.get_page_margins().get_bottom())); auto decimal = n.find('.');
page_margins_node.add_attribute("header", std::to_string(sheet_.get_page_margins().get_header()));
page_margins_node.add_attribute("footer", std::to_string(sheet_.get_page_margins().get_footer())); if (decimal == std::string::npos) return n;
auto index = n.size() - 1;
while (index >= decimal && n[index] == '0')
{
index--;
}
if(index == decimal)
{
return n.substr(0, decimal);
}
return n.substr(0, index + 1);
};
page_margins_node.add_attribute("left", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_left())));
page_margins_node.add_attribute("right", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_right())));
page_margins_node.add_attribute("top", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_top())));
page_margins_node.add_attribute("bottom", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_bottom())));
page_margins_node.add_attribute("header", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_header())));
page_margins_node.add_attribute("footer", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_footer())));
if (!sheet_.get_page_setup().is_default()) if (!sheet_.get_page_setup().is_default())
{ {

View File

@ -85,11 +85,13 @@ bool manifest::has_override_type(const std::string &part_name) const
void manifest::add_default_type(const std::string &extension, const std::string &content_type) void manifest::add_default_type(const std::string &extension, const std::string &content_type)
{ {
if(has_default_type(extension)) return;
default_types_.push_back(default_type(extension, content_type)); default_types_.push_back(default_type(extension, content_type));
} }
void manifest::add_override_type(const std::string &part_name, const std::string &content_type) void manifest::add_override_type(const std::string &part_name, const std::string &content_type)
{ {
if(has_override_type(part_name)) return;
override_types_.push_back(override_type(part_name, content_type)); override_types_.push_back(override_type(part_name, content_type));
} }

View File

@ -42,9 +42,20 @@ workbook_impl::workbook_impl()
workbook::workbook() : d_(new detail::workbook_impl()) workbook::workbook() : d_(new detail::workbook_impl())
{ {
create_sheet("Sheet"); create_sheet("Sheet");
create_relationship("rId2", "sharedStrings.xml", relationship::type::shared_strings); create_relationship("rId2", "sharedStrings.xml", relationship::type::shared_strings);
create_relationship("rId3", "styles.xml", relationship::type::styles); create_relationship("rId3", "styles.xml", relationship::type::styles);
create_relationship("rId4", "theme/theme1.xml", relationship::type::theme); create_relationship("rId4", "theme/theme1.xml", relationship::type::theme);
d_->manifest_.add_default_type("rels", "application/vnd.openxmlformats-package.relationships+xml");
d_->manifest_.add_default_type("xml", "application/xml");
d_->manifest_.add_override_type("/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
d_->manifest_.add_override_type("/xl/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml");
d_->manifest_.add_override_type("/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
d_->manifest_.add_override_type("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");
d_->manifest_.add_override_type("/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml");
d_->manifest_.add_override_type("/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml");
} }
workbook::iterator::iterator(workbook &wb, std::size_t index) : wb_(wb), index_(index) workbook::iterator::iterator(workbook &wb, std::size_t index) : wb_(wb), index_(index)
@ -159,11 +170,15 @@ worksheet workbook::create_sheet()
title = "Sheet" + std::to_string(++index); title = "Sheet" + std::to_string(++index);
} }
std::string sheet_filename = "worksheets/sheet" + std::to_string(d_->worksheets_.size() + 1) + ".xml";
d_->worksheets_.push_back(detail::worksheet_impl(this, title)); d_->worksheets_.push_back(detail::worksheet_impl(this, title));
create_relationship("rId" + std::to_string(d_->relationships_.size() + 1), create_relationship("rId" + std::to_string(d_->relationships_.size() + 1),
"xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml", sheet_filename,
relationship::type::worksheet); relationship::type::worksheet);
d_->manifest_.add_override_type("/xl/" + sheet_filename, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");
return worksheet(&d_->worksheets_.back()); return worksheet(&d_->worksheets_.back());
} }
@ -300,7 +315,7 @@ void workbook::remove_sheet(worksheet ws)
throw std::runtime_error("worksheet not owned by this workbook"); throw std::runtime_error("worksheet not owned by this workbook");
} }
auto sheet_filename = "xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml"; auto sheet_filename = "worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml";
auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(), auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(),
[=](relationship &r) { return r.get_target_uri() == sheet_filename; }); [=](relationship &r) { return r.get_target_uri() == sheet_filename; });
@ -558,6 +573,11 @@ void workbook::add_font(const font &font_)
void workbook::add_number_format(const number_format &number_format_) void workbook::add_number_format(const number_format &number_format_)
{ {
d_->number_formats_.push_back(number_format_); d_->number_formats_.push_back(number_format_);
if(number_format_.get_id() == -1)
{
d_->number_formats_.back().set_id(d_->next_custom_format_id_++);
}
} }
void workbook::set_code_name(const std::string & /*code_name*/) void workbook::set_code_name(const std::string & /*code_name*/)
@ -867,6 +887,12 @@ const std::vector<std::string> &workbook::get_shared_strings() const
void workbook::add_shared_string(const std::string &shared) void workbook::add_shared_string(const std::string &shared)
{ {
//TODO: inefficient, use a set or something?
for(auto &s : d_->shared_strings_)
{
if(s == shared) return;
}
d_->shared_strings_.push_back(shared); d_->shared_strings_.push_back(shared);
} }

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1" /> <outlinePr summaryBelow="1" summaryRight="1" />
</sheetPr> </sheetPr>
<dimension ref="A1:F42" /> <dimension ref="F42:F42" />
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<selection activeCell="A1" sqref="A1" /> <selection activeCell="A1" sqref="A1" />

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1" /> <outlinePr summaryBelow="1" summaryRight="1" />
</sheetPr> </sheetPr>
<dimension ref="A1:F42"/> <dimension ref="F42:F42"/>
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<selection activeCell="A1" sqref="A1" /> <selection activeCell="A1" sqref="A1" />

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1" /> <outlinePr summaryBelow="1" summaryRight="1" />
</sheetPr> </sheetPr>
<dimension ref="A1:F43" /> <dimension ref="F42:F43" />
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<selection activeCell="A1" sqref="A1" /> <selection activeCell="A1" sqref="A1" />

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1"/> <outlinePr summaryBelow="1" summaryRight="1"/>
</sheetPr> </sheetPr>
<dimension ref="A1:F3"/> <dimension ref="F1:F3"/>
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<selection activeCell="A1" sqref="A1"/> <selection activeCell="A1" sqref="A1"/>

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1"/> <outlinePr summaryBelow="1" summaryRight="1"/>
</sheetPr> </sheetPr>
<dimension ref="A1:F42"/> <dimension ref="F42:F42"/>
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<pane xSplit="3" ySplit="3" topLeftCell="D4" activePane="bottomRight" state="frozen"/> <pane xSplit="3" ySplit="3" topLeftCell="D4" activePane="bottomRight" state="frozen"/>

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1"/> <outlinePr summaryBelow="1" summaryRight="1"/>
</sheetPr> </sheetPr>
<dimension ref="A1:F42"/> <dimension ref="F42:F42"/>
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<pane ySplit="3" topLeftCell="A4" activePane="bottomLeft" state="frozen"/> <pane ySplit="3" topLeftCell="A4" activePane="bottomLeft" state="frozen"/>

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1"/> <outlinePr summaryBelow="1" summaryRight="1"/>
</sheetPr> </sheetPr>
<dimension ref="A1:F42"/> <dimension ref="F42:F42"/>
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<pane xSplit="3" topLeftCell="D1" activePane="topRight" state="frozen"/> <pane xSplit="3" topLeftCell="D1" activePane="topRight" state="frozen"/>

View File

@ -3,7 +3,7 @@
<sheetPr> <sheetPr>
<outlinePr summaryBelow="1" summaryRight="1"/> <outlinePr summaryBelow="1" summaryRight="1"/>
</sheetPr> </sheetPr>
<dimension ref="A1:F1"/> <dimension ref="F1:F1"/>
<sheetViews> <sheetViews>
<sheetView workbookViewId="0"> <sheetView workbookViewId="0">
<selection activeCell="A1" sqref="A1"/> <selection activeCell="A1" sqref="A1"/>

View File

@ -14,12 +14,9 @@ class test_props : public CxxTest::TestSuite
public: public:
void test_read_properties_core() void test_read_properties_core()
{ {
xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"); auto path = PathHelper::GetDataDirectory() + "/genuine/empty.xlsx";
auto content = archive.read("docProps/core.xml");
xlnt::workbook wb; xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb); wb.load(path);
xlnt::xml_document xml;
serializer.read_properties_core(xml);
auto &prop = wb.get_properties(); auto &prop = wb.get_properties();
TS_ASSERT_EQUALS(prop.creator, "*.*"); TS_ASSERT_EQUALS(prop.creator, "*.*");
TS_ASSERT_EQUALS(prop.last_modified_by, "Charlie Clark"); TS_ASSERT_EQUALS(prop.last_modified_by, "Charlie Clark");
@ -29,19 +26,18 @@ public:
void test_read_sheets_titles() void test_read_sheets_titles()
{ {
xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"); auto path = PathHelper::GetDataDirectory() + "/genuine/empty.xlsx";
auto content = archive.read("docProps/core.xml");
const std::vector<std::string> expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; const std::vector<std::string> expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"};
std::size_t i = 0; std::size_t i = 0;
xlnt::workbook wb; xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb); wb.load(path);
for(auto sheet : serializer.read_sheets()) for(auto sheet : wb)
{ {
TS_ASSERT_EQUALS(sheet.second, expected_titles.at(i++)); TS_ASSERT_EQUALS(sheet.get_title(), expected_titles.at(i++));
} }
} }
@ -59,19 +55,18 @@ public:
void test_read_sheets_titles_libre() void test_read_sheets_titles_libre()
{ {
xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx"); auto path = PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx";
auto content = archive.read("docProps/core.xml");
const std::vector<std::string> expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; const std::vector<std::string> expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"};
std::size_t i = 0; std::size_t i = 0;
xlnt::workbook wb; xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb); wb.load(path);
for(auto sheet : serializer.read_sheets()) for(auto sheet : wb)
{ {
TS_ASSERT_EQUALS(sheet.second, expected_titles.at(i++)); TS_ASSERT_EQUALS(sheet.get_title(), expected_titles.at(i++));
} }
} }
@ -83,8 +78,6 @@ public:
prop.last_modified_by = "SOMEBODY"; prop.last_modified_by = "SOMEBODY";
prop.created = xlnt::datetime(2010, 4, 1, 20, 30, 00); prop.created = xlnt::datetime(2010, 4, 1, 20, 30, 00);
prop.modified = xlnt::datetime(2010, 4, 5, 14, 5, 30); prop.modified = xlnt::datetime(2010, 4, 5, 14, 5, 30);
TS_FAIL("");
return;
xlnt::workbook_serializer serializer(wb); xlnt::workbook_serializer serializer(wb);
xlnt::xml_document xml = serializer.write_properties_core(); xlnt::xml_document xml = serializer.write_properties_core();
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/core.xml", xml)); TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/core.xml", xml));
@ -97,8 +90,6 @@ public:
wb.create_sheet(); wb.create_sheet();
xlnt::workbook_serializer serializer(wb); xlnt::workbook_serializer serializer(wb);
xlnt::xml_document xml = serializer.write_properties_app(); xlnt::xml_document xml = serializer.write_properties_app();
TS_FAIL("");
return;
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/app.xml", xml)); TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/app.xml", xml));
} }
}; };

View File

@ -327,64 +327,16 @@ public:
TS_ASSERT(!ws.get_cell("A5").has_formula()); TS_ASSERT(!ws.get_cell("A5").has_formula());
} }
void test_detect_worksheets()
{
{
auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx");
xlnt::zip_file archive(path);
std::vector<std::pair<std::string, std::string>> expected =
{
{"xl/worksheets/sheet1.xml", "Sheet1"}
};
xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb);
TS_ASSERT_EQUALS(serializer.detect_worksheets(), expected);
}
{
auto path = PathHelper::GetDataDirectory("/reader/contains_chartsheets.xlsx");
xlnt::zip_file archive(path);
std::vector<std::pair<std::string, std::string>> expected =
{
{"xl/worksheets/sheet1.xml", "data"},
{"xl/worksheets/sheet2.xml", "moredata"}
};
xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb);
TS_ASSERT_EQUALS(serializer.detect_worksheets(), expected);
}
{
auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx");
xlnt::zip_file archive(path);
std::vector<std::pair<std::string, std::string>> expected =
{
{"xl/worksheets/sheet3.xml", "Sheet1"},
{"xl/worksheets/sheet2.xml", "Sheet2"},
{"xl/worksheets/sheet.xml", "Sheet3"}
};
xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb);
TS_ASSERT_EQUALS(serializer.detect_worksheets(), expected);
}
}
void test_read_rels() void test_read_rels()
{ {
{ {
std::vector<xlnt::relationship> expected = std::vector<xlnt::relationship> expected =
{ {
{xlnt::relationship::type::theme, "rId3", "xl/theme/theme1.xml"}, {xlnt::relationship::type::theme, "rId3", "theme/theme1.xml"},
{xlnt::relationship::type::worksheet, "rId2", "xl/worksheets/sheet1.xml"}, {xlnt::relationship::type::worksheet, "rId2", "worksheets/sheet1.xml"},
{xlnt::relationship::type::chartsheet, "rId1", "xl/chartsheets/sheet1.xml"}, {xlnt::relationship::type::chartsheet, "rId1", "chartsheets/sheet1.xml"},
{xlnt::relationship::type::shared_strings, "rId5", "xl/sharedStrings.xml"}, {xlnt::relationship::type::shared_strings, "rId5", "sharedStrings.xml"},
{xlnt::relationship::type::styles, "rId4", "xl/styles.xml"} {xlnt::relationship::type::styles, "rId4", "styles.xml"}
}; };
auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx"); auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx");
@ -397,13 +349,13 @@ public:
std::vector<xlnt::relationship> expected = std::vector<xlnt::relationship> expected =
{ {
{xlnt::relationship::type::custom_xml, "rId8", "../customXml/item3.xml"}, {xlnt::relationship::type::custom_xml, "rId8", "../customXml/item3.xml"},
{xlnt::relationship::type::worksheet, "rId3", "xl/worksheets/sheet.xml"}, {xlnt::relationship::type::worksheet, "rId3", "/xl/worksheets/sheet.xml"},
{xlnt::relationship::type::custom_xml, "rId7", "../customXml/item2.xml"}, {xlnt::relationship::type::custom_xml, "rId7", "../customXml/item2.xml"},
{xlnt::relationship::type::worksheet, "rId2", "xl/worksheets/sheet2.xml"}, {xlnt::relationship::type::worksheet, "rId2", "/xl/worksheets/sheet2.xml"},
{xlnt::relationship::type::worksheet, "rId1", "xl/worksheets/sheet3.xml"}, {xlnt::relationship::type::worksheet, "rId1", "/xl/worksheets/sheet3.xml"},
{xlnt::relationship::type::custom_xml, "rId6", "../customXml/item1.xml"}, {xlnt::relationship::type::custom_xml, "rId6", "../customXml/item1.xml"},
{xlnt::relationship::type::styles, "rId5", "xl/styles.xml"}, {xlnt::relationship::type::styles, "rId5", "/xl/styles.xml"},
{xlnt::relationship::type::theme, "rId4", "xl/theme/theme.xml"} {xlnt::relationship::type::theme, "rId4", "/xl/theme/theme.xml"}
}; };
auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx"); auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx");
@ -436,12 +388,7 @@ public:
auto path = PathHelper::GetDataDirectory("/reader/contains_chartsheets.xlsx"); auto path = PathHelper::GetDataDirectory("/reader/contains_chartsheets.xlsx");
xlnt::workbook wb; xlnt::workbook wb;
xlnt::manifest_serializer serializer(wb.get_manifest()); wb.load(path);
xlnt::zip_file archive;
archive.load(path);
serializer.read_manifest(xlnt::xml_serializer::deserialize(archive.read("[Content Types].xml")));
auto &result = wb.get_manifest().get_override_types(); auto &result = wb.get_manifest().get_override_types();
@ -453,35 +400,8 @@ public:
for(std::size_t i = 0; i < expected.size(); i++) for(std::size_t i = 0; i < expected.size(); i++)
{ {
TS_ASSERT_EQUALS(result[i].get_part_name(), expected[i].first); TS_ASSERT(wb.get_manifest().has_override_type(expected[i].first));
TS_ASSERT_EQUALS(result[i].get_content_type(), expected[i].second); TS_ASSERT_EQUALS(wb.get_manifest().get_override_type(expected[i].first), expected[i].second);
}
}
void test_read_sheets()
{
{
auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx");
xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb);
auto sheets = serializer.read_sheets();
std::vector<std::pair<std::string, std::string>> expected =
{{"rId1", "Chart1"}, {"rId2", "Sheet1"}};
TS_ASSERT_EQUALS(sheets, expected);
}
{
auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx");
xlnt::workbook wb;
xlnt::workbook_serializer serializer(wb);
auto sheets = serializer.read_sheets();
std::vector<std::pair<std::string, std::string>> expected =
{{"rId1", "Sheet1"}, {"rId2", "Sheet2"}, {"rId3", "Sheet3"}};
TS_ASSERT_EQUALS(sheets, expected);
} }
} }

View File

@ -16,11 +16,9 @@ public:
xlnt::xml_document observed; xlnt::xml_document observed;
writer.write_number_formats(observed.add_child("numFmts")); writer.write_number_formats(observed.add_child("numFmts"));
std::string expected = std::string expected =
"<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"
" <numFmts count=\"1\">" " <numFmts count=\"1\">"
" <numFmt formatCode=\"YYYY\" numFmtId=\"164\"></numFmt>" " <numFmt formatCode=\"YYYY\" numFmtId=\"164\"></numFmt>"
" </numFmts>" " </numFmts>";
"</styleSheet>";
auto diff = Helper::compare_xml(expected, observed); auto diff = Helper::compare_xml(expected, observed);
TS_ASSERT(diff); TS_ASSERT(diff);
} }

View File

@ -703,8 +703,8 @@ public:
void test_merge() void test_merge()
{ {
xlnt::worksheet ws(wb_); xlnt::workbook clean_wb; // for shared strings
std::vector<std::string> string_table = {"Cell A1", "Cell B1"}; xlnt::worksheet ws(clean_wb);
auto expected_string1 = auto expected_string1 =
"<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">" "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
@ -904,13 +904,13 @@ public:
" </headerFooter>" " </headerFooter>"
"</worksheet>"; "</worksheet>";
xlnt::xml_document expected;
expected.from_string(expected_xml_string);
{ {
xlnt::worksheet_serializer serializer(ws); xlnt::worksheet_serializer serializer(ws);
auto observed = serializer.write_worksheet(); auto observed = serializer.write_worksheet();
xlnt::xml_document expected;
expected.from_string(expected_xml_string);
TS_ASSERT(Helper::compare_xml(expected, observed)); TS_ASSERT(Helper::compare_xml(expected, observed));
} }
@ -936,6 +936,9 @@ public:
xlnt::worksheet_serializer serializer(ws); xlnt::worksheet_serializer serializer(ws);
auto observed = serializer.write_worksheet(); auto observed = serializer.write_worksheet();
xlnt::xml_document expected;
expected.from_string(expected_xml_string);
TS_ASSERT(Helper::compare_xml(expected, observed)); TS_ASSERT(Helper::compare_xml(expected, observed));
} }
} }

View File

@ -138,7 +138,9 @@ public:
void test_write_hyperlink() void test_write_hyperlink()
{ {
auto ws = wb_.create_sheet(); xlnt::workbook clean_wb;
auto ws = clean_wb.get_active_sheet();
ws.get_cell("A1").set_value("test"); ws.get_cell("A1").set_value("test");
ws.get_cell("A1").set_hyperlink("http://test.com"); ws.get_cell("A1").set_hyperlink("http://test.com");

View File

@ -98,7 +98,7 @@ public:
xlnt::zip_file archive; xlnt::zip_file archive;
xlnt::relationship_serializer::write_relationships(wb.get_relationships(), "xl/workbook.xml", archive); xlnt::relationship_serializer::write_relationships(wb.get_relationships(), "xl/workbook.xml", archive);
xlnt::xml_document observed; xlnt::xml_document observed;
observed.from_string(archive.read("xl/workbook/_rels/workbook.xml.rels")); observed.from_string(archive.read("xl/_rels/workbook.xml.rels"));
auto filename = "workbook.xml.rels"; auto filename = "workbook.xml.rels";
auto diff = Helper::compare_xml(PathHelper::read_file(filename), observed); auto diff = Helper::compare_xml(PathHelper::read_file(filename), observed);
TS_ASSERT(!diff); TS_ASSERT(!diff);