void test_hemp_text_config() { Hemp hemp = hemp_new(); ok( hemp, "created hemp object" ); hemp_language(hemp, "json"); HEMP_TRY; hemp_configure_from( hemp, "json", "text", "{ hemp: { dir: '/else/where', path: ['here', '/there'] } }" ); pass("configured from text"); test_hemp_config(hemp, "hemp.dir", "/else/where"); //test_hemp_config(hemp, "hemp.path", "here/there"); hemp_codec(hemp, "uri"); HEMP_CATCH_ALL; fail("caught error: %s", hemp->error->message); HempText error = hemp_error_text(hemp->error); printf("%s", error->string); hemp_text_free(error); HEMP_END; hemp_free(hemp); }
HEMP_INLINE void hemp_text_clean( HempValue value ) { HempText text = hemp_val_text(value); // hemp_debug_msg("releasing text @ %p: %s\n", text, text->string) ; hemp_text_free(text); }
void test_hemp() { Hemp hemp = hemp_new(); ok( hemp, "created hemp object" ); HEMP_TRY; HempString version = hemp_version(); ok( version, "got hemp version: %s", version ); /* test the global configuration */ HempValue cfghemp = hemp_config_get(hemp, "hemp"); ok( hemp_is_defined(cfghemp), "fetched hemp config" ); test_hemp_config(hemp, "hemp.version", version); test_hemp_config(hemp, "hemp.dir", HEMP_DIR); test_hemp_config(hemp, "hemp.module_dir", HEMP_MODULE_DIR); test_hemp_config(hemp, "hemp.module_ext", HEMP_MODULE_EXT); /* add some extra configuration values from a hash */ HempHash config = hemp_hash_new(); hemp_hash_store_string(config, "foo", "Hello"); hemp_hash_store_string(config, "bar", "World"); hemp_hash_store_string(config, "hemp.dir", "/some/where/else"); /* add a nested hemp.root value to mask the global config value */ HempHash hconf = hemp_hash_new(); hemp_hash_store_hash(config, "hemp", hconf); hemp_hash_store_string(hconf, "dir", "/some/where/else"); /* configure the hemp object from the hash and check values */ hemp_configure(hemp, hemp_hash_val(config)); test_hemp_config(hemp, "foo", "Hello"); test_hemp_config(hemp, "bar", "World"); test_hemp_config(hemp, "hemp.dir", "/some/where/else"); test_hemp_config(hemp, "hemp.version", version); /* read configuration from a file */ hemp_language(hemp, "json"); // FIXME hemp_configure_from(hemp, "json", "file", HEMP_TEST_DIR "/data/config1.json"); test_hemp_config(hemp, "hemp.dir", "/dir/from/config1"); test_hemp_config(hemp, "hemp.animal", "badger"); test_hemp_config(hemp, "extra.cheese", "please"); hemp_hash_free(hconf); hemp_hash_free(config); HEMP_CATCH_ALL; fail("caught error: %s", hemp->error->message); HempText error = hemp_error_text(hemp->error); printf("%s", error->string); hemp_text_free(error); HEMP_END; hemp_free(hemp); }
HempBool hemp_list_index( HempContext context, HempValue key, HempInt *index ) { hemp_debug_call("hemp_list_index()\n"); HempBool found = HEMP_FALSE; if (hemp_is_integer(key)) { // hemp_debug("got integer key\n"); *index = hemp_val_int(key); found = HEMP_TRUE; } else { HempText ktext; HempBool kmine = HEMP_FALSE; if (hemp_is_text(key)) { // hemp_debug("got text key\n"); ktext = hemp_val_text(key); } else { /* otherwise we have to convert the key to text */ /* TODO: must be a better way to check for numeric conversion without throwing an error? */ // hemp_debug("creating text key\n"); ktext = hemp_text_new_size(16); kmine = HEMP_TRUE; hemp_onto_text(key, context, hemp_text_val(ktext)); } // hemp_debug("list text key: %s\n", ktext->string); if (hemp_string_intlike(ktext->string)) { // hemp_debug("got numlike string\n"); *index = hemp_val_int( hemp_type_string_integer( hemp_str_val(ktext->string), context) ); found = HEMP_TRUE; } else { // hemp_debug("text index is not numlike: %s\n", ktext->string); } if (kmine) hemp_text_free(ktext); } return found; }
void test_viewer() { Hemp hemp = hemp_new(); ok( hemp, "created hemp object" ); hemp_language(hemp, "tt3"); HempDocument document = hemp_document( hemp, HEMP_TT3, HEMP_TEXT, "Hello [% name %]!" ); ok( document , "created document" ); HempContext context = hemp_context(hemp); ok( context, "created hemp context" ); ok( hemp_context_set_string(context, "name", "World"), "set name" ); HempViewer text = hemp_viewer(hemp, "text"); ok( text, "created text view" ); is( text->name, "text", "name is set: text" ); text = hemp_viewer(hemp, "text"); ok( text, "fetched text view again" ); HempText output; HEMP_TRY; output = hemp_document_render(document, context); ok( output, "rendered document"); HEMP_CATCH_ALL; output = hemp_error_text(hemp->error); HEMP_END; printf("** OUTPUT ** : %s\n", output->string); hemp_text_free(output); HempFragment root = hemp_document_tree(document); ok( root, "got root element: %p", root); HempValue result = hemp_viewer_fragment(text, root, context, HempNothing); HEMP_UNUSED(result); hemp_context_free(context); hemp_free(hemp); }
void test_types() { Hemp hemp = hemp_new(); HempContext context = hemp_context(hemp); HempValue number = hemp_num_val(3.14159); ok( hemp_is_number(number), "created a number" ); HempMemory method; method = hemp_object_method(number, "name"); ok( method, "got a pointer to name method"); HempValue value = hemp_send(number, "name", context); ok( hemp_is_defined(value), "got result" ); is( hemp_val_str(value), "Number", "got number name" ); value = hemp_send(number, "no_such_method", context); ok( hemp_is_missing(value), "no_such_method is missing" ); HempText text = hemp_text_from_string("hello world!"); value = hemp_send( hemp_text_val(text), "length", context); ok( hemp_is_defined(value), "got text length" ); eq( hemp_val_int(value), 12, "length is 12" ); hemp_text_free(text); /* try converting number to text */ value = hemp_send(value, "text", context); if (hemp_is_missing(value)) { fail("No text method?"); exit(1); } ok( hemp_is_defined(value), "got length as text" ); is( hemp_val_text(value)->string, "12", "length text is 12" ); // Text value is now managed by context // hemp_text_free( hemp_val_text(value) ); hemp_context_free(context); hemp_free(hemp); }
HempUint hemp_test_expect_text( HempString language, HempString dialect, HempString text, HempString alias, HempContext context ) { Hemp hemp = hemp_new(); HempString test, name, expect, error, end; HempList list; HempDocument document; HempText output; HempSize n; HEMP_TRY; hemp_language(hemp, language); HEMP_CATCH_ALL; hemp_fatal("Failed to load hemp language '%s': %s", language, hemp->error->message); HEMP_END; if ((test = strstr(text, HEMP_TEST_START))) { hemp_string_to_next_line(&test); } else { test = text; } if ((end = strstr(text, HEMP_TEST_STOP))) *end = HEMP_NUL; test = strstr(test, HEMP_TEST_MARKER); if (! test) hemp_fatal("no tests found in %s", alias); /* skip over first -- test */ test += strlen(HEMP_TEST_MARKER); list = hemp_string_split(test, HEMP_TEST_MARKER); hemp_debug("found %d tests in %s\n", list->length, alias); // hemp_test_plan(list->length * 2); hemp_test_plan(list->length); for (n = 0; n < list->length; n++) { test = hemp_val_str( hemp_list_item(list, n) ); /* skip over leading whitespace */ while (isspace(*test)) { test++; } name = test; do { test++; } while (*test != HEMP_LF && *test != HEMP_CR); /* NUL terminate test name */ *test = '\0'; do { test++; } while (*test == HEMP_LF || *test == HEMP_CR); if ((expect = strstr(test, HEMP_EXPECT_MARKER))) { *expect = '\0'; expect += strlen(HEMP_EXPECT_MARKER); hemp_string_to_next_line(&expect); } if ( (error = strstr(test, HEMP_ERROR_MARKER)) || (expect && (error = strstr(expect, HEMP_ERROR_MARKER )))) { *error = '\0'; error += strlen(HEMP_ERROR_MARKER); hemp_string_to_next_line(&error); } hemp_string_chomp(test); // printf(">> test %u: %s\n", n, name); // if (expect) // printf(">> expect [%s]\n", expect); // if (error) // printf(">> error [%s]\n", error); HEMP_TRY; document = hemp_document( hemp, HEMP_TT3, HEMP_TEXT, test ); output = hemp_document_render(document, context); // ok( output, "%s (rendered)", name); if (expect) hemp_test_output(name, output, expect); else if (error) fail("expected error but got output"); HEMP_CATCH_ALL; output = hemp_error_text(hemp->error); if (error) { // pass("%s", name); hemp_test_error(name, output->string, error); } else { fail("%s (error: %s)", name, output->string); // fail("error: %s", output->string); } HEMP_END; hemp_text_free(output); } hemp_list_free(list); hemp_free(hemp); return hemp_test_done(NULL); }
HempModule hemp_use_module( Hemp hemp, HempString type, HempString name ) { hemp_debug_call("hemp_use_module(%s => %s)\n", type, name); HempValue path = hemp_config_get(hemp, HEMP_CONFIG_MODPATH); HempString string; if (hemp_is_defined(path)) { string = hemp_to_string(path, hemp->context); // hemp_debug_msg("already got %s: %s\n", HEMP_CONFIG_MODPATH, string); } else { HempValue dir = hemp_config_get(hemp, HEMP_CONFIG_DIR); HempValue mod = hemp_config_get(hemp, HEMP_CONFIG_MODDIR); HempString dstr = hemp_to_string(dir, hemp->context); HempString mstr = hemp_to_string(mod, hemp->context); string = hemp_uri_path_join(dstr, mstr, 1); // hemp_debug_msg("constructed %s: %s\n", HEMP_CONFIG_MODPATH, string); /* ugly work-around so we can get the context to manage memory */ HempText text = hemp_context_tmp_text_size(hemp->context, strlen(string) + 1); hemp_text_append_string(text, string); hemp_mem_free(string); string = text->string; // hemp_config_set(hemp, HEMP_CONFIG_MODPATH, hemp_text_val(text)); } // TODO: need a way to save dotted path (hemp.module_path) back into config /* quick hack to get something working */ HempString modpath = getenv("HEMP_MODULE_PATH"); if (! modpath || ! *modpath) { modpath = string; // hemp_debug_msg("No HEMP_MODULE_PATH environment variable set\n"); // return HEMP_FALSE; } /* TODO: sort this mess out */ HempString tpath = hemp_uri_path_join(modpath, type, 1); HempString mpath = hemp_uri_path_join(tpath, name, 1); HempText mtext = hemp_text_from_string(mpath); hemp_text_append_string(mtext, HEMP_MODULE_EXT); hemp_mem_free(mpath); hemp_mem_free(tpath); // hemp_debug_msg("constructed module path: %s\n", mtext->string); HempModule module = hemp_global_module(hemp->global, mtext->string); if (module->binder) { module->binder(module, hemp); } else if (module->error) { hemp_fatal(module->error); } else { /* should never happen - famous last word */ hemp_fatal("No binder function for %s module", name); } hemp_text_free(mtext); return module; }