/* * Copyright 2009-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at: * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific * language governing permissions and limitations under the License. */ #include #include #include "cli.h" #include "ion_test_util.h" #include "gather_vectors.h" #include "ion_event_util.h" void test_ion_cli_assert_error_equals(IonEventErrorDescription *actual, ION_EVENT_ERROR_TYPE expected_type, iERR expected_code, std::string expected_location_suffix="", int expected_event_index=-1) { ASSERT_EQ(expected_type, actual->error_type); if (expected_event_index >= 0) { ASSERT_TRUE(actual->has_event_index); ASSERT_EQ((size_t)expected_event_index, actual->event_index); } if (!expected_location_suffix.empty()) { ASSERT_TRUE(actual->has_location); ASSERT_EQ(expected_location_suffix, actual->location.substr(actual->location.size() - expected_location_suffix.length())); } ASSERT_NE(actual->message.find(ion_error_to_str(expected_code)), actual->message.npos); } void test_ion_cli_assert_comparison_result_equals(IonEventComparisonResult *actual, ION_EVENT_COMPARISON_RESULT_TYPE expected_type, std::string expected_lhs_location, std::string expected_rhs_location, size_t expected_lhs_index, size_t expected_rhs_index) { ASSERT_EQ(expected_type, actual->result); ASSERT_NE(actual->lhs.location.npos, actual->lhs.location.find(expected_lhs_location)) << actual->lhs.location; ASSERT_NE(actual->rhs.location.npos, actual->rhs.location.find(expected_rhs_location)) << actual->rhs.location; ASSERT_EQ(expected_lhs_index, actual->lhs.event_index); ASSERT_EQ(expected_rhs_index, actual->rhs.event_index); } void test_ion_cli_init_common_args(IonCliCommonArgs *common_args, ION_EVENT_OUTPUT_TYPE output_format=OUTPUT_TYPE_TEXT_UGLY, const char *error_report="stdout", ION_CLI_IO_TYPE error_type=IO_TYPE_CONSOLE) { common_args->output = IonCliIO(); common_args->output.type = IO_TYPE_MEMORY; common_args->output_format = output_format; common_args->error_report = IonCliIO(error_report, error_type); } void test_ion_cli_add_input(const char *input, ION_CLI_IO_TYPE input_type, IonCliCommonArgs *common_args) { common_args->input_files.push_back(IonCliIO(input, input_type)); } void test_ion_cli_add_catalog(const char *catalog, ION_CLI_IO_TYPE input_type, IonCliCommonArgs *common_args) { common_args->catalogs.push_back(IonCliIO(catalog, input_type)); } void test_ion_cli_init_process_args(IonCliProcessArgs *process_args) { } void test_ion_cli_add_import(const char *import, ION_CLI_IO_TYPE input_type, IonCliProcessArgs *process_args) { process_args->imports.push_back(IonCliIO(import, input_type)); } void test_ion_cli_process(const char *input, ION_CLI_IO_TYPE input_type, ION_STRING *command_output, IonEventReport *report, ION_EVENT_OUTPUT_TYPE output_format=OUTPUT_TYPE_TEXT_UGLY) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; test_ion_cli_init_common_args(&common_args, output_format); test_ion_cli_add_input(input, input_type, &common_args); test_ion_cli_init_process_args(&process_args); ion_cli_command_process(&common_args, &process_args, command_output, report); } void test_ion_cli_compare(const char *input, ION_CLI_IO_TYPE input_type, ION_STRING *command_output, IonEventReport *report, ION_EVENT_COMPARISON_TYPE comparison_type, ION_EVENT_OUTPUT_TYPE output_format=OUTPUT_TYPE_TEXT_UGLY) { IonCliCommonArgs common_args; test_ion_cli_init_common_args(&common_args, output_format); test_ion_cli_add_input(input, input_type, &common_args); ion_cli_command_compare(&common_args, comparison_type, command_output, report); } void test_ion_cli_read_stream_successfully(BYTE *data, size_t data_len, IonEventStream *stream) { hREADER reader; IonEventResult result; ION_ASSERT_OK(ion_test_new_reader(data, (SIZE)data_len, &reader)); ION_ASSERT_OK(ion_event_stream_read_all(reader, NULL, stream, &result)); ION_ASSERT_OK(ion_reader_close(reader)); ASSERT_FALSE(result.has_error_description); ASSERT_FALSE(result.has_comparison_result); } void test_ion_cli_assert_streams_equal(const char *expected_str, ION_STRING *actual_str) { IonEventStream expected("expected"), actual("actual"); IonEventResult result; test_ion_cli_read_stream_successfully((BYTE *)expected_str, strlen(expected_str), &expected); test_ion_cli_read_stream_successfully(actual_str->value, (size_t)actual_str->length, &actual); ASSERT_TRUE(ion_compare_streams(&expected, &actual, &result)); ASSERT_FALSE(result.has_comparison_result); ASSERT_FALSE(result.has_error_description); } TEST(IonCli, ProcessBasic) { ION_STRING command_output; IonEventReport report; test_ion_cli_process(join_path(full_good_path, "one.ion").c_str(), IO_TYPE_FILE, &command_output, &report, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); test_ion_cli_assert_streams_equal("1", &command_output); test_ion_cli_assert_streams_equal("$ion_event_stream {event_type:SCALAR, ion_type:INT, value_text:\"1\", value_binary:[0xE0, 0x01, 0x00, 0xEA, 0x21, 0x01], depth: 0} {event_type: STREAM_END, depth: 0}", &command_output); ion_cli_free_command_output(&command_output); } TEST(IonCli, UnequalValueTextAndValueBinaryFails) { // Text value is integer 1, binary value is integer 2 const char *event_stream = "$ion_event_stream {event_type:SCALAR, ion_type:INT, value_text:\"1\", value_binary:[0xE0, 0x01, 0x00, 0xEA, 0x21, 0x02], depth: 0} {event_type: STREAM_END, depth: 0}"; IonEventReport report; ION_STRING command_output; ION_STRING_INIT(&command_output); test_ion_cli_process(event_stream, IO_TYPE_MEMORY, &command_output, &report); ASSERT_TRUE(report.hasErrors()); test_ion_cli_assert_error_equals(&report.getErrors()->at(0), ERROR_TYPE_STATE, IERR_INVALID_ARG, event_stream); ASSERT_TRUE(report.hasComparisonFailures()); test_ion_cli_assert_comparison_result_equals(&report.getComparisonResults()->at(0), COMPARISON_RESULT_NOT_EQUAL, event_stream, event_stream, 0, 0); ASSERT_EQ(0, command_output.length); ion_cli_free_command_output(&command_output); } void test_ion_cli_assert_comparison(std::string *files, size_t num_files, ION_EVENT_COMPARISON_TYPE comparison_type, IonEventReport *report) { IonCliCommonArgs common_args; ION_STRING _command_output; ION_STRING_INIT(&_command_output); test_ion_cli_init_common_args(&common_args); for (size_t i = 0; i < num_files; i++) { test_ion_cli_add_input(files[i].c_str(), IO_TYPE_FILE, &common_args); } ION_ASSERT_OK(ion_cli_command_compare(&common_args, comparison_type, &_command_output, report)); ion_cli_free_command_output(&_command_output); } TEST(IonCli, CompareNullsBasic) { std::string test_file = join_path(full_good_path, "allNulls.ion"); IonEventReport report; test_ion_cli_assert_comparison(&test_file, 1, COMPARISON_TYPE_BASIC, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_FALSE(report.hasComparisonFailures()); } TEST(IonCli, CompareListsEquivs) { std::string test_file = join_path(full_good_equivs_path, "lists.ion"); IonEventReport report; test_ion_cli_assert_comparison(&test_file, 1, COMPARISON_TYPE_EQUIVS, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_FALSE(report.hasComparisonFailures()); } TEST(IonCli, CompareNonEquivalentIntsAsEquivs) { std::string test_file = join_path(full_good_nonequivs_path, "ints.ion"); IonEventReport report; test_ion_cli_assert_comparison(&test_file, 1, COMPARISON_TYPE_EQUIVS, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_TRUE(report.hasComparisonFailures()); std::vector *comparison_results = report.getComparisonResults(); ASSERT_EQ(1, comparison_results->size()); test_ion_cli_assert_comparison_result_equals(&comparison_results->at(0), COMPARISON_RESULT_NOT_EQUAL, test_file, test_file, 1, 2); } TEST(IonCli, CompareSexpsNonequivs) { std::string test_file = join_path(full_good_nonequivs_path, "sexps.ion"); IonEventReport report; test_ion_cli_assert_comparison(&test_file, 1, COMPARISON_TYPE_NONEQUIVS, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_FALSE(report.hasComparisonFailures()); } TEST(IonCli, CompareEquivalentIntsAsNonequivs) { std::string test_file = join_path(full_good_equivs_path, "ints.ion"); IonEventReport report; test_ion_cli_assert_comparison(&test_file, 1, COMPARISON_TYPE_NONEQUIVS, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_TRUE(report.hasComparisonFailures()); std::vector *comparison_results = report.getComparisonResults(); ASSERT_EQ(1, comparison_results->size()); test_ion_cli_assert_comparison_result_equals(&comparison_results->at(0), COMPARISON_RESULT_EQUAL, test_file, test_file, 1, 2); } TEST(IonCli, CompareAnnotatedIvmsEmbeddedNonequivs) { std::string test_file = join_path(full_good_nonequivs_path, "annotatedIvms.ion"); IonEventReport report; // NOTE: this is a non-equivs file being compared for equivs; comparison failures are expected. test_ion_cli_assert_comparison(&test_file, 1, COMPARISON_TYPE_EQUIVS, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_TRUE(report.hasComparisonFailures()); std::vector *comparison_results = report.getComparisonResults(); ASSERT_EQ(1, comparison_results->size()); test_ion_cli_assert_comparison_result_equals(&comparison_results->at(0), COMPARISON_RESULT_NOT_EQUAL, test_file, test_file, 1, 3); } TEST(IonCli, CompareMultipleInputFiles) { std::string test_files[3]; test_files[0] = join_path(full_good_path, "one.ion"); test_files[1] = join_path(full_good_path, "one.ion"); test_files[2] = join_path(full_good_path, "empty.ion"); IonEventReport report; test_ion_cli_assert_comparison(test_files, 3, COMPARISON_TYPE_BASIC, &report); ASSERT_FALSE(report.hasErrors()); ASSERT_TRUE(report.hasComparisonFailures()); std::vector *comparison_results = report.getComparisonResults(); ASSERT_EQ(4, comparison_results->size()); // one vs empty, one vs empty, empty vs one, empty vs one test_ion_cli_assert_comparison_result_equals(&comparison_results->at(0), COMPARISON_RESULT_NOT_EQUAL, test_files[0], test_files[2], 0, 0); test_ion_cli_assert_comparison_result_equals(&comparison_results->at(1), COMPARISON_RESULT_NOT_EQUAL, test_files[1], test_files[2], 0, 0); test_ion_cli_assert_comparison_result_equals(&comparison_results->at(2), COMPARISON_RESULT_NOT_EQUAL, test_files[2], test_files[0], 0, 0); test_ion_cli_assert_comparison_result_equals(&comparison_results->at(3), COMPARISON_RESULT_NOT_EQUAL, test_files[2], test_files[1], 0, 0); } TEST(IonCli, ErrorIsConveyed) { std::string test_file = join_path(full_bad_path, "annotationFalse.ion"); ION_STRING command_output; IonEventReport report; test_ion_cli_process(test_file.c_str(), IO_TYPE_FILE, &command_output, &report); ASSERT_TRUE(report.hasErrors()); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_EQ(5, command_output.length); test_ion_cli_assert_error_equals(&report.getErrors()->at(0), ERROR_TYPE_READ, IERR_INVALID_SYNTAX, test_file); ion_cli_free_command_output(&command_output); } TEST(IonCli, ErrorIsConveyedEvents) { std::string test_file = join_path(full_bad_path, "fieldNameFalse.ion"); ION_STRING command_output; IonEventReport report; test_ion_cli_process(test_file.c_str(), IO_TYPE_FILE, &command_output, &report, OUTPUT_TYPE_EVENTS); ASSERT_TRUE(report.hasErrors()); ASSERT_FALSE(report.hasComparisonFailures()); test_ion_cli_assert_error_equals(&report.getErrors()->at(0), ERROR_TYPE_READ, IERR_INVALID_FIELDNAME, test_file); test_ion_cli_assert_streams_equal("$ion_event_stream {event_type:CONTAINER_START, ion_type:STRUCT, depth: 0}", &command_output); ion_cli_free_command_output(&command_output); } TEST(IonCli, ErrorIsConveyedComparison) { // This should fail because equivs comparisons must involve sequence types. const char *data = "1 2"; IonEventReport report; IonCliCommonArgs common_args; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(data, IO_TYPE_MEMORY, &common_args); ion_cli_command_compare(&common_args, COMPARISON_TYPE_EQUIVS, NULL, &report); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_TRUE(report.hasErrors()); test_ion_cli_assert_error_equals(&report.getErrors()->at(0), ERROR_TYPE_STATE, IERR_INVALID_STATE, data); } TEST(IonCli, AnnotatedIvmsEmbedded) { std::string test_file = join_path(full_good_nonequivs_path, "annotatedIvms.ion"); ION_STRING command_output; ION_STRING_INIT(&command_output); IonEventReport report; IonEventStream stream(test_file); test_ion_cli_process(test_file.c_str(), IO_TYPE_FILE, &command_output, &report, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report.hasErrors()); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(ION_STRING_IS_NULL(&command_output)); test_ion_cli_read_stream_successfully(command_output.value, (size_t)command_output.length, &stream); ASSERT_EQ(CONTAINER_START, stream.at(0)->event_type); ASSERT_EQ(0, stream.at(0)->depth); ASSERT_EQ(SCALAR, stream.at(1)->event_type); ASSERT_EQ(tid_SYMBOL, stream.at(1)->ion_type); ASSERT_EQ(1, stream.at(1)->num_annotations); ASSERT_EQ(0, stream.at(1)->depth); ASSERT_EQ(STREAM_END, stream.at(2)->event_type); ASSERT_EQ(STREAM_END, stream.at(3)->event_type); ASSERT_EQ(CONTAINER_END, stream.at(4)->event_type); ASSERT_EQ(0, stream.at(4)->depth); ion_cli_free_command_output(&command_output); } TEST(IonCli, ComparisonSetsDifferentLengthsEquivsSucceeds) { const char *lhs_data = "(1 0x1 0b1)"; const char *rhs_data = "(0x1 1)"; IonEventReport report; IonCliCommonArgs common_args; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(lhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(rhs_data, IO_TYPE_MEMORY, &common_args); ion_cli_command_compare(&common_args, COMPARISON_TYPE_EQUIVS, NULL, &report); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); // Reverse the order of the inputs. test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(rhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(lhs_data, IO_TYPE_MEMORY, &common_args); ion_cli_command_compare(&common_args, COMPARISON_TYPE_EQUIVS, NULL, &report); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); } TEST(IonCli, ComparisonSetsDifferentLengthsNonequivsSucceeds) { const char *lhs_data = "(1)"; const char *rhs_data = "(2 3)"; IonEventReport report; IonCliCommonArgs common_args; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(lhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(rhs_data, IO_TYPE_MEMORY, &common_args); ion_cli_command_compare(&common_args, COMPARISON_TYPE_NONEQUIVS, NULL, &report); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); // Reverse the order of the inputs. test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(rhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(lhs_data, IO_TYPE_MEMORY, &common_args); ion_cli_command_compare(&common_args, COMPARISON_TYPE_NONEQUIVS, NULL, &report); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); } TEST(IonCli, BasicProcessWithCatalog) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; IonEventReport report; ION_STRING command_output; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input( "$ion_symbol_table::{symbols:[\"def\"], imports:[{name:\"foo\", version:1, max_id:1}]} $10::$11", IO_TYPE_MEMORY, &common_args); test_ion_cli_add_catalog("$ion_shared_symbol_table::{name:\"foo\", version:1, symbols:[\"abc\"]}", IO_TYPE_MEMORY, &common_args); test_ion_cli_init_process_args(&process_args); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_process(&common_args, &process_args, &command_output, &report)); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); test_ion_cli_assert_streams_equal("abc::def", &command_output); ion_cli_free_command_output(&command_output); } TEST(IonCli, ProcessWithImportsAndCatalog) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; IonEventReport report; ION_STRING command_output; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input( "$ion_symbol_table::{imports:[{name:\"foo\", version:1, max_id:1}]} $10", IO_TYPE_MEMORY, &common_args); test_ion_cli_add_catalog("$ion_shared_symbol_table::{name:\"foo\", version:1, symbols:[\"abc\"]}", IO_TYPE_MEMORY, &common_args); test_ion_cli_init_process_args(&process_args); test_ion_cli_add_import("{name:\"foo\", version:1, max_id:1}", IO_TYPE_MEMORY, &process_args); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_process(&common_args, &process_args, &command_output, &report)); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); test_ion_cli_assert_streams_equal("abc", &command_output); ion_cli_free_command_output(&command_output); } TEST(IonCli, ProcessWithImportsAndWithoutCatalog) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; IonEventReport report; ION_STRING command_output; const char *data = "$ion_symbol_table::{imports:[{name:\"foo\", version:1, max_id:1}]} $10"; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(data, IO_TYPE_MEMORY, &common_args); test_ion_cli_init_process_args(&process_args); test_ion_cli_add_import("{name:\"foo\", version:1, max_id:1}", IO_TYPE_MEMORY, &process_args); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_process(&common_args, &process_args, &command_output, &report)); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); test_ion_cli_assert_streams_equal(data, &command_output); ion_cli_free_command_output(&command_output); } TEST(IonCli, BasicCompareWithCatalog) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; IonEventReport report; ION_STRING command_output; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input( "$ion_symbol_table::{symbols:[\"def\"], imports:[{name:\"foo\", version:1, max_id:1}]} $10::$11", IO_TYPE_MEMORY, &common_args); test_ion_cli_add_catalog("$ion_shared_symbol_table::{name:\"foo\", version:1, symbols:[\"abc\"]}", IO_TYPE_MEMORY, &common_args); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_compare(&common_args, COMPARISON_TYPE_BASIC, &command_output, &report)); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); ion_cli_free_command_output(&command_output); } TEST(IonCli, CompareWithResultsWithCatalog) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; IonEventReport report; ION_STRING command_output; const char *lhs_data = "$ion_symbol_table::{symbols:[\"def\"], imports:[{name:\"foo\", version:1, max_id:1}]} $10::$11"; const char *rhs_data = "$ion_symbol_table::{symbols:[\"ghi\"], imports:[{name:\"foo\", version:1, max_id:1}]} $10::$11"; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(lhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(rhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_catalog("$ion_shared_symbol_table::{name:\"foo\", version:1, symbols:[\"abc\"]}", IO_TYPE_MEMORY, &common_args); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_compare(&common_args, COMPARISON_TYPE_BASIC, &command_output, &report)); ASSERT_TRUE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); test_ion_cli_assert_comparison_result_equals(&report.getComparisonResults()->at(0), COMPARISON_RESULT_NOT_EQUAL, lhs_data, rhs_data, 1, 1); test_ion_cli_assert_comparison_result_equals(&report.getComparisonResults()->at(1), COMPARISON_RESULT_NOT_EQUAL, rhs_data, lhs_data, 1, 1); ion_cli_free_command_output(&command_output); } TEST(IonCli, CompareWithResultsWithoutCatalog) { IonCliCommonArgs common_args; IonCliProcessArgs process_args; IonEventReport report; ION_STRING command_output; const char *lhs_data = "$ion_symbol_table::{symbols:[\"def\"], imports:[{name:\"foo\", version:1, max_id:1}]} $10::$11"; const char *rhs_data = "$ion_symbol_table::{symbols:[\"def\"], imports:[{name:\"bar\", version:1, max_id:1}]} $10::$11"; test_ion_cli_init_common_args(&common_args); test_ion_cli_add_input(lhs_data, IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(rhs_data, IO_TYPE_MEMORY, &common_args); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_compare(&common_args, COMPARISON_TYPE_BASIC, &command_output, &report)); ASSERT_TRUE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); test_ion_cli_assert_comparison_result_equals(&report.getComparisonResults()->at(0), COMPARISON_RESULT_NOT_EQUAL, lhs_data, rhs_data, 1, 1); test_ion_cli_assert_comparison_result_equals(&report.getComparisonResults()->at(1), COMPARISON_RESULT_NOT_EQUAL, rhs_data, lhs_data, 1, 1); ion_cli_free_command_output(&command_output); } TEST(IonCli, ProcessSymbolsWithUnknownTextWithoutCatalog) { IonEventReport report; ION_STRING command_output; ION_STRING_INIT(&command_output); std::string filepath = join_path(full_good_path, "item1.10n"); test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); IonCliCommonArgs common_args; test_ion_cli_init_common_args(&common_args); IonEventStream stream; std::string event_data = std::string((char *)command_output.value, (size_t)command_output.length); test_ion_cli_add_input(event_data.c_str(), IO_TYPE_MEMORY, &common_args); test_ion_cli_add_input(filepath.c_str(), IO_TYPE_FILE, &common_args); ion_cli_free_command_output(&command_output); ION_STRING_INIT(&command_output); ION_ASSERT_OK(ion_cli_command_compare(&common_args, COMPARISON_TYPE_BASIC, &command_output, &report)); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_FALSE(report.hasErrors()); ion_cli_free_command_output(&command_output); } TEST(IonCli, EventWithDuplicateFieldFails) { const char *data = "$ion_event_stream {event_type: STREAM_END, depth: 0, event_type: STREAM_END}"; ION_STRING command_output; IonEventReport report; ION_STRING_INIT(&command_output); test_ion_cli_process(data, IO_TYPE_MEMORY, &command_output, &report); ASSERT_FALSE(report.hasComparisonFailures()); ASSERT_TRUE(report.hasErrors()); ASSERT_EQ(0, command_output.length); test_ion_cli_assert_error_equals(&report.getErrors()->at(0), ERROR_TYPE_STATE, IERR_INVALID_ARG, data); ion_cli_free_command_output(&command_output); } TEST(IonCli, FirstValueHasError) { const char *data = "+"; IonEventReport report1, report2; ION_STRING command_output; ION_STRING_INIT(&command_output); test_ion_cli_process(data, IO_TYPE_MEMORY, &command_output, &report1, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report1.hasComparisonFailures()); ASSERT_TRUE(report1.hasErrors()); char *events = ion_string_strdup(&command_output); test_ion_cli_process(events, IO_TYPE_MEMORY, &command_output, &report2); ASSERT_FALSE(report2.hasComparisonFailures()); ASSERT_FALSE(report2.hasErrors()); ASSERT_EQ(0, command_output.length); free(events); } TEST(IonCli, ParsingFailureDoesNotYieldEvent) { IonEventReport report1, report2; ION_STRING command_output; ION_STRING_INIT(&command_output); std::string filepath = join_path(full_bad_path, "dateWithZ.ion"); test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report1, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report1.hasComparisonFailures()); ASSERT_TRUE(report1.hasErrors()); char *events = ion_string_strdup(&command_output); test_ion_cli_process(events, IO_TYPE_MEMORY, &command_output, &report2); ASSERT_FALSE(report2.hasComparisonFailures()); ASSERT_FALSE(report2.hasErrors()); ASSERT_EQ(0, command_output.length); free(events); } TEST(IonCli, ComparingBadListWithElementsFromEventStreamSucceeds) { IonEventReport report1, report2; ION_STRING command_output; ION_STRING_INIT(&command_output); std::string filepath = join_path(full_bad_path, "annotationWithoutValue.ion"); test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report1, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report1.hasComparisonFailures()); ASSERT_TRUE(report1.hasErrors()); char *events = ion_string_strdup(&command_output); test_ion_cli_compare(events, IO_TYPE_MEMORY, &command_output, &report2, COMPARISON_TYPE_BASIC); ASSERT_FALSE(report2.hasComparisonFailures()); ASSERT_FALSE(report2.hasErrors()); free(events); } TEST(IonCli, ComparingBadListWithoutElementsFromEventStreamSucceeds) { IonEventReport report1, report2; ION_STRING command_output; ION_STRING_INIT(&command_output); std::string filepath = join_path(full_bad_path, "list_4.ion"); test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report1, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report1.hasComparisonFailures()); ASSERT_TRUE(report1.hasErrors()); char *events = ion_string_strdup(&command_output); test_ion_cli_compare(events, IO_TYPE_MEMORY, &command_output, &report2, COMPARISON_TYPE_BASIC); ASSERT_FALSE(report2.hasComparisonFailures()); ASSERT_FALSE(report2.hasErrors()); free(events); } TEST(IonCli, ComparingSymbolZeroFromEventStreamSucceeds) { IonEventReport report1, report2; ION_STRING command_output; ION_STRING_INIT(&command_output); std::string filepath = join_path(full_good_path, "symbolZero.ion"); test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report1, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report1.hasComparisonFailures()); ASSERT_FALSE(report1.hasErrors()); char *events = ion_string_strdup(&command_output); test_ion_cli_compare(events, IO_TYPE_MEMORY, &command_output, &report2, COMPARISON_TYPE_BASIC); ASSERT_FALSE(report2.hasComparisonFailures()); ASSERT_FALSE(report2.hasErrors()); free(events); } TEST(IonCli, ComparingInnerVersionMarkersSucceeds) { IonEventReport report1, report2; ION_STRING command_output; ION_STRING_INIT(&command_output); std::string filepath = join_path(full_good_path, "innerVersionIdentifiers.ion"); test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report1, OUTPUT_TYPE_EVENTS); ASSERT_FALSE(report1.hasComparisonFailures()); ASSERT_FALSE(report1.hasErrors()); char *events = ion_string_strdup(&command_output); test_ion_cli_compare(events, IO_TYPE_MEMORY, &command_output, &report2, COMPARISON_TYPE_BASIC); ASSERT_FALSE(report2.hasComparisonFailures()); ASSERT_FALSE(report2.hasErrors()); free(events); }