// // test-csnowcrash.cc // snowcrash // // Created by Ali Khoramshahi on 3/7/14. // Copyright (c) 2014 Apiary Inc. All rights reserved. // #include "snowcrashtest.h" #include "csnowcrash.h" TEST_CASE("Parse simple blueprint with C interface", "[cinterface]") { mdp::ByteBuffer source = \ "FORMAT: 1A\n"\ "\n"\ "# My API\n"\ "Description of *My API*.\n"\ "\n"\ "## Message [/message]\n"\ "### GET\n"\ "+ Response 200 (text/plain)\n"\ "\n"\ " Hello World!\n"\ "\n"\ "# Group test\n"\ "\n"\ "## Message [/message]\n"; sc_report_t* report; sc_blueprint_t* blueprint; sc_sm_blueprint_t* sm_blueprint; sc_c_parse(source.c_str(), SC_REQUIRE_BLUEPRINT_NAME_OPTION | SC_EXPORT_SORUCEMAP_OPTION, &report, &blueprint, &sm_blueprint); const sc_warnings_t* warns = sc_warnings_handler(report); REQUIRE(sc_warnings_size(warns) == 1); const sc_warning_t* warn = sc_warning_handler(warns, 0); REQUIRE(std::string(sc_warning_message(warn)) == "the resource '/message' is already defined" ); const sc_metadata_collection_t* meta_col = sc_metadata_collection_handle(blueprint); const sc_sm_metadata_collection_t* sm_meta_col = sc_sm_metadata_collection_handle(sm_blueprint); REQUIRE(sc_metadata_collection_size(meta_col) == 1); REQUIRE(sc_sm_metadata_collection_size(sm_meta_col) == 1); const sc_metadata_t* meta = sc_metadata_handle(meta_col, 0); REQUIRE(std::string(sc_metadata_key(meta)) == "FORMAT" ); REQUIRE(std::string(sc_metadata_value(meta)) == "1A" ); const sc_source_map_t* sm_meta = sc_sm_metadata(sc_sm_metadata_handle(sm_meta_col, 0)); REQUIRE(sc_source_map_size(sm_meta) == 1); REQUIRE(sc_source_map_location(sm_meta, 0) == 0); REQUIRE(sc_source_map_length(sm_meta, 0) == 12); const sc_resource_group_collection_t* res_gr_col = sc_resource_group_collection_handle(blueprint); const sc_sm_resource_group_collection_t* sm_res_gr_col = sc_sm_resource_group_collection_handle(sm_blueprint); REQUIRE(sc_resource_group_collection_size(res_gr_col) == 2); REQUIRE(sc_sm_resource_group_collection_size(sm_res_gr_col) == 2); const sc_resource_group_t* res_gr = sc_resource_group_handle(res_gr_col, 0); const sc_sm_resource_group_t* sm_res_gr = sc_sm_resource_group_handle(sm_res_gr_col, 0); REQUIRE(std::string(sc_resource_group_name(res_gr)) == ""); const sc_source_map_t* sm_res_gr_name = sc_sm_resource_group_name(sm_res_gr); REQUIRE(sc_source_map_size(sm_res_gr_name) == 0); const sc_resource_collection_t* re_col = sc_resource_collection_handle(res_gr); const sc_sm_resource_collection_t* sm_re_col = sc_sm_resource_collection_handle(sm_res_gr); REQUIRE(sc_resource_collection_size(re_col) == 1); REQUIRE(sc_sm_resource_collection_size(sm_re_col) == 1); const sc_resource_t* res = sc_resource_handle(re_col, 0); const sc_sm_resource_t* sm_res = sc_sm_resource_handle(sm_re_col, 0); REQUIRE(std::string(sc_resource_uritemplate(res)) == "/message"); const sc_source_map_t* sm_res_uritemplate = sc_sm_resource_uritemplate(sm_res); REQUIRE(sc_source_map_size(sm_res_uritemplate) == 1); REQUIRE(sc_source_map_location(sm_res_uritemplate, 0) == 47); REQUIRE(sc_source_map_length(sm_res_uritemplate, 0) == 22); const sc_action_collection_t* act_col = sc_action_collection_handle(res); const sc_sm_action_collection_t* sm_act_col = sc_sm_action_collection_handle(sm_res); REQUIRE(sc_action_collection_size(act_col) == 1); REQUIRE(sc_sm_action_collection_size(sm_act_col) == 1); const sc_action_t* act = sc_action_handle(act_col, 0); const sc_sm_action_t* sm_act = sc_sm_action_handle(sm_act_col, 0); REQUIRE(std::string(sc_action_httpmethod(act)) == "GET"); const sc_source_map_t* sm_act_httpmethod = sc_sm_action_httpmethod(sm_act); REQUIRE(sc_source_map_size(sm_act_httpmethod) == 1); REQUIRE(sc_source_map_location(sm_act_httpmethod, 0) == 69); REQUIRE(sc_source_map_length(sm_act_httpmethod, 0) == 8); const sc_transaction_example_collection_t* trans_col = sc_transaction_example_collection_handle(act); const sc_sm_transaction_example_collection_t* sm_trans_col = sc_sm_transaction_example_collection_handle(sm_act); REQUIRE(sc_transaction_example_collection_size(trans_col) == 1); REQUIRE(sc_sm_transaction_example_collection_size(sm_trans_col) == 1); const sc_transaction_example_t* trans = sc_transaction_example_handle(trans_col, 0); const sc_sm_transaction_example_t* sm_trans = sc_sm_transaction_example_handle(sm_trans_col, 0); REQUIRE(std::string(sc_transaction_example_name(trans)) == ""); const sc_source_map_t* sm_trans_name = sc_sm_transaction_example_name(sm_trans); REQUIRE(sc_source_map_size(sm_trans_name) == 0); const sc_payload_collection_t* resp_col = sc_payload_collection_handle_responses(trans); const sc_sm_payload_collection_t* sm_resp_col = sc_sm_payload_collection_handle_responses(sm_trans); REQUIRE(sc_payload_collection_size(resp_col) == 1); REQUIRE(sc_sm_payload_collection_size(sm_resp_col) == 1); const sc_payload_t* resp = sc_payload_handle(resp_col, 0); const sc_sm_payload_t* sm_resp = sc_sm_payload_handle(sm_resp_col, 0); REQUIRE(std::string(sc_payload_name(resp)) == "200"); REQUIRE(std::string(sc_payload_body(resp)) == "Hello World!\n"); const sc_source_map_t* sm_resp_name = sc_sm_payload_name(sm_resp); const sc_source_map_t* sm_resp_body = sc_sm_payload_body(sm_resp); REQUIRE(sc_source_map_size(sm_resp_name) == 1); REQUIRE(sc_source_map_location(sm_resp_name, 0) == 79); REQUIRE(sc_source_map_length(sm_resp_name, 0) == 27); REQUIRE(sc_source_map_size(sm_resp_body) == 1); REQUIRE(sc_source_map_location(sm_resp_body, 0) == 110); REQUIRE(sc_source_map_length(sm_resp_body, 0) == 17); const sc_header_collection_t* header_col = sc_header_collection_handle_payload(resp); const sc_sm_header_collection_t* sm_header_col = sc_sm_header_collection_handle_payload(sm_resp); REQUIRE(sc_header_collection_size(header_col) == 1); REQUIRE(sc_sm_header_collection_size(sm_header_col) == 1); const sc_header_t* header = sc_header_handle(header_col, 0); REQUIRE(std::string(sc_header_key(header)) == "Content-Type"); REQUIRE(std::string(sc_header_value(header)) == "text/plain"); const sc_source_map_t* sm_header = sc_sm_header(sc_sm_header_handle(sm_header_col, 0)); REQUIRE(sc_source_map_size(sm_header) == 1); REQUIRE(sc_source_map_location(sm_header, 0) == 79); REQUIRE(sc_source_map_length(sm_header, 0) == 27); sc_sm_blueprint_free(sm_blueprint); sc_blueprint_free(blueprint); sc_report_free(report); } TEST_CASE("Parse blueprint with multiple requests and responses via C interface", "[cinterface]") { const std::string blueprintSource = \ "# /resource\n"\ "## GET\n"\ "\n"\ "+ request A\n"\ "\n"\ " A\n"\ "\n"\ "+ response 200\n"\ "\n"\ " 200-A\n"\ "\n"\ "+ request B\n"\ "\n"\ " B\n"\ "\n"\ "+ response 200\n"\ "\n"\ " 200-B\n"\ "\n"; sc_report_t* report; sc_blueprint_t* blueprint; sc_sm_blueprint_t* sm_blueprint; sc_c_parse(blueprintSource.c_str(), SC_RENDER_DESCRIPTIONS_OPTION | SC_EXPORT_SORUCEMAP_OPTION, &report, &blueprint, &sm_blueprint); const sc_resource_group_collection_t* res_gr_col = sc_resource_group_collection_handle(blueprint); const sc_sm_resource_group_collection_t* sm_res_gr_col = sc_sm_resource_group_collection_handle(sm_blueprint); REQUIRE(sc_resource_group_collection_size(res_gr_col) == 1); REQUIRE(sc_sm_resource_group_collection_size(sm_res_gr_col) == 1); const sc_resource_group_t* res_gr = sc_resource_group_handle(res_gr_col, 0); const sc_sm_resource_group_t* sm_res_gr = sc_sm_resource_group_handle(sm_res_gr_col, 0); REQUIRE(std::string(sc_resource_group_name(res_gr)) == ""); const sc_source_map_t* sm_res_gr_name = sc_sm_resource_group_name(sm_res_gr); REQUIRE(sc_source_map_size(sm_res_gr_name) == 0); const sc_resource_collection_t* re_col = sc_resource_collection_handle(res_gr); const sc_sm_resource_collection_t* sm_re_col = sc_sm_resource_collection_handle(sm_res_gr); REQUIRE(sc_resource_collection_size(re_col) == 1); REQUIRE(sc_sm_resource_collection_size(sm_re_col) == 1); const sc_resource_t* res = sc_resource_handle(re_col, 0); const sc_sm_resource_t* sm_res = sc_sm_resource_handle(sm_re_col, 0); REQUIRE(std::string(sc_resource_uritemplate(res)) == "/resource"); const sc_source_map_t* sm_res_uritemplate = sc_sm_resource_uritemplate(sm_res); REQUIRE(sc_source_map_size(sm_res_uritemplate) == 1); REQUIRE(sc_source_map_location(sm_res_uritemplate, 0) == 0); REQUIRE(sc_source_map_length(sm_res_uritemplate, 0) == 12); const sc_action_collection_t* act_col = sc_action_collection_handle(res); const sc_sm_action_collection_t* sm_act_col = sc_sm_action_collection_handle(sm_res); REQUIRE(sc_action_collection_size(act_col) == 1); REQUIRE(sc_sm_action_collection_size(sm_act_col) == 1); const sc_action_t* act = sc_action_handle(act_col, 0); const sc_sm_action_t* sm_act = sc_sm_action_handle(sm_act_col, 0); REQUIRE(std::string(sc_action_httpmethod(act)) == "GET"); const sc_source_map_t* sm_act_httpmethod = sc_sm_action_httpmethod(sm_act); REQUIRE(sc_source_map_size(sm_act_httpmethod) == 1); REQUIRE(sc_source_map_location(sm_act_httpmethod, 0) == 12); REQUIRE(sc_source_map_length(sm_act_httpmethod, 0) == 8); const sc_transaction_example_collection_t* trans_col = sc_transaction_example_collection_handle(act); const sc_sm_transaction_example_collection_t* sm_trans_col = sc_sm_transaction_example_collection_handle(sm_act); REQUIRE(sc_transaction_example_collection_size(trans_col) == 2); REQUIRE(sc_sm_transaction_example_collection_size(sm_trans_col) == 2); sc_sm_blueprint_free(sm_blueprint); sc_blueprint_free(blueprint); sc_report_free(report); } TEST_CASE("CBlueprint issue on sc_resource_group_handle", "[cinterface]") { const std::string blueprintSource = \ "# My API\n"\ "\n"\ "# Group A\n"\ "## /Resource A1\n"\ "### GET\n"\ "+ Response 200\n"\ "\n"\ " A1\n"\ "\n"\ "# Group B\n"\ "## /Resource B1\n"\ "### GET\n"\ "+ Response 200\n"\ "\n"\ " B1\n"\ "\n"\ "## /Resource B2\n"\ "### GET\n"\ "+ Response 200\n"\ "\n"\ " B2\n"\ "\n"; sc_report_t* report; sc_blueprint_t* blueprint; sc_sm_blueprint_t* sm_blueprint; sc_c_parse(blueprintSource.c_str(), 0, &report, &blueprint, &sm_blueprint); const sc_resource_group_collection_t* res_gr_col = sc_resource_group_collection_handle(blueprint); const sc_resource_group_t* res_gr1 = sc_resource_group_handle(res_gr_col, 0); const sc_resource_group_t* res_gr2 = sc_resource_group_handle(res_gr_col, 1); const sc_sm_resource_group_collection_t* sm_res_gr_col = sc_sm_resource_group_collection_handle(sm_blueprint); REQUIRE(sc_sm_resource_group_collection_size(sm_res_gr_col) == 0); REQUIRE(sc_resource_group_collection_size(res_gr_col) == 2); REQUIRE(std::string(sc_resource_group_name(res_gr1)) == "A"); REQUIRE(std::string(sc_resource_group_name(res_gr2)) == "B"); const sc_resource_collection_t* res_col1 = sc_resource_collection_handle(res_gr1); REQUIRE(sc_resource_collection_size(res_col1) == 1); const sc_resource_collection_t* res_col2 = sc_resource_collection_handle(res_gr2); REQUIRE(sc_resource_collection_size(res_col2) == 2); sc_sm_blueprint_free(sm_blueprint); sc_blueprint_free(blueprint); sc_report_free(report); } TEST_CASE("Parse blueprint with multiple reference via C interface", "[cinterface]") { const std::string blueprintSource = \ "#api name\n\n"\ "# Resource 1 [/1]\n"\ "+ Model (text/plain)\n\n"\ " `resource model` 1\n\n"\ "# Resource 2 [/2]\n"\ "## Retrieve [GET]\n\n"\ "+ Response 200\n\n"\ " [Resource 1][]\n\n"\ "# Resource 3 [/3]\n"\ "## Retrieve [GET]\n\n"\ "+ Response 200\n\n"\ " [Resource 4][]\n\n"\ "# Resource 4 [/4]\n"\ "+ Model (text/plain)\n\n"\ " `resource model` 4\n"; sc_report_t* report; sc_blueprint_t* blueprint; sc_sm_blueprint_t* sm_blueprint; sc_c_parse(blueprintSource.c_str(), 0, &report, &blueprint, &sm_blueprint); const sc_resource_group_collection_t* res_gr_col = sc_resource_group_collection_handle(blueprint); REQUIRE(sc_resource_group_collection_size(res_gr_col) == 1); const sc_resource_group_t* res_gr = sc_resource_group_handle(res_gr_col, 0); REQUIRE(std::string(sc_resource_group_name(res_gr)) == ""); const sc_resource_collection_t* sm_res_gr_col = sc_resource_collection_handle(res_gr); REQUIRE(sc_resource_collection_size(sm_res_gr_col) == 4); const sc_resource_t *res = sc_resource_handle(sm_res_gr_col, 1); REQUIRE(std::string(sc_resource_uritemplate(res)) == "/2"); REQUIRE(std::string(sc_resource_name(res)) == "Resource 2"); const sc_action_collection_t* action_col = sc_action_collection_handle(res); REQUIRE(sc_action_collection_size(action_col) == 1); const sc_action_t* action = sc_action_handle(action_col, 0); REQUIRE(std::string(sc_action_httpmethod(action)) == "GET"); REQUIRE(std::string(sc_action_name(action)) == "Retrieve"); const sc_transaction_example_collection_t* example_col = sc_transaction_example_collection_handle(action); REQUIRE(sc_transaction_example_collection_size(example_col) == 1); const sc_transaction_example_t* example = sc_transaction_example_handle(example_col, 0); REQUIRE(std::string(sc_transaction_example_name(example)) == ""); const sc_payload_collection_t* response_col = sc_payload_collection_handle_responses(example); REQUIRE(sc_payload_collection_size(response_col) == 1); const sc_payload_t* response = sc_payload_handle(response_col, 0); REQUIRE(std::string(sc_payload_name(response)) == "200"); REQUIRE(std::string(sc_payload_body(response)) == "`resource model` 1\n"); const sc_reference_t* reference = sc_reference_handle_payload(response); REQUIRE(std::string(sc_reference_id(reference)) == "Resource 1"); REQUIRE(sc_reference_type(reference) == 0); res = sc_resource_handle(sm_res_gr_col, 2); REQUIRE(std::string(sc_resource_uritemplate(res)) == "/3"); REQUIRE(std::string(sc_resource_name(res)) == "Resource 3"); action_col = sc_action_collection_handle(res); REQUIRE(sc_action_collection_size(action_col) == 1); action = sc_action_handle(action_col, 0); REQUIRE(std::string(sc_action_httpmethod(action)) == "GET"); REQUIRE(std::string(sc_action_name(action)) == "Retrieve"); example_col = sc_transaction_example_collection_handle(action); REQUIRE(sc_transaction_example_collection_size(example_col) == 1); example = sc_transaction_example_handle(example_col, 0); REQUIRE(std::string(sc_transaction_example_name(example)) == ""); response_col = sc_payload_collection_handle_responses(example); REQUIRE(sc_payload_collection_size(response_col) == 1); response = sc_payload_handle(response_col, 0); REQUIRE(std::string(sc_payload_name(response)) == "200"); REQUIRE(std::string(sc_payload_body(response)) == "`resource model` 4\n"); reference = sc_reference_handle_payload(response); REQUIRE(std::string(sc_reference_id(reference)) == "Resource 4"); REQUIRE(sc_reference_type(reference) == 0); sc_sm_blueprint_free(sm_blueprint); sc_blueprint_free(blueprint); sc_report_free(report); }