Path: blob/main/contrib/libucl/tests/test_generate.c
39586 views
/* Copyright (c) 2013, Vsevolod Stakhov1* All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10*11* THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY12* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED13* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE14* DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY15* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES16* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;17* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND18* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT19* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS20* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.21*/2223#include <stdio.h>24#include <errno.h>25#include <assert.h>26#include "ucl.h"2728static void29ud_dtor (void *ptr)30{31assert (ptr == NULL);32}3334static const char *35ud_emit (void *ptr)36{37return "test userdata emit";38}3940int41main (int argc, char **argv)42{43ucl_object_t *obj, *cur, *ar, *ar1, *ref, *test_obj, *comments;44ucl_object_iter_t it;45const ucl_object_t *found, *it_obj, *test;46struct ucl_emitter_functions *fn;47FILE *out;48unsigned char *emitted;49const char *fname_out = NULL;50struct ucl_parser *parser;51int ret = 0;5253switch (argc) {54case 2:55fname_out = argv[1];56break;57}585960if (fname_out != NULL) {61out = fopen (fname_out, "w");62if (out == NULL) {63exit (-errno);64}65}66else {67out = stdout;68}6970obj = ucl_object_typed_new (UCL_OBJECT);7172/* Keys replacing */73cur = ucl_object_fromstring_common ("value1", 0, UCL_STRING_TRIM);74ucl_object_insert_key (obj, cur, "key0", 0, false);75cur = ucl_object_fromdouble (0.1);76assert (ucl_object_replace_key (obj, cur, "key0", 0, false));7778/* Create some strings */79cur = ucl_object_fromstring_common (" test string ", 0, UCL_STRING_TRIM);80ucl_object_insert_key (obj, cur, "key1", 0, false);81cur = ucl_object_fromstring_common (" test \nstring\n\r\n\b\t\f\\\" ", 0,82UCL_STRING_TRIM | UCL_STRING_ESCAPE);83ucl_object_insert_key (obj, cur, "key2", 0, false);84cur = ucl_object_fromstring_common (" test string \n", 0, 0);85ucl_object_insert_key (obj, cur, "key3", 0, false);86/* Array of numbers */87ar = ucl_object_typed_new (UCL_ARRAY);88cur = ucl_object_fromint (10);89ucl_array_append (ar, cur);90assert (ucl_array_index_of (ar, cur) == 0);91cur = ucl_object_fromdouble (10.1);92ucl_array_append (ar, cur);93assert (ucl_array_index_of (ar, cur) == 1);94cur = ucl_object_fromdouble (9.999);95ucl_array_prepend (ar, cur);96assert (ucl_array_index_of (ar, cur) == 0);9798ar1 = ucl_object_copy (ar);99cur = ucl_object_fromstring ("abc");100ucl_array_prepend (ar1, cur);101cur = ucl_object_fromstring ("cde");102ucl_array_prepend (ar1, cur);103cur = ucl_object_fromstring ("абв"); /* UTF8 */104ucl_array_prepend (ar1, cur);105cur = ucl_object_fromstring ("Ебв"); /* UTF8 */106ucl_array_prepend (ar1, cur);107/*108* This is usually broken or fragile as utf collate is far from perfect109cur = ucl_object_fromstring ("ёбв");110ucl_array_prepend (ar1, cur);111cur = ucl_object_fromstring ("Ёбв"); // hello to @bapt112ucl_array_prepend (ar1, cur);113*/114cur = ucl_object_fromstring ("😎"); /* everybody likes emoji in the code */115ucl_array_prepend (ar1, cur);116117ucl_object_array_sort (ar1, ucl_object_compare_qsort);118119/* Removing from an array */120cur = ucl_object_fromdouble (1.0);121ucl_array_append (ar, cur);122cur = ucl_array_delete (ar, cur);123assert (ucl_object_todouble (cur) == 1.0);124ucl_object_unref (cur);125cur = ucl_object_fromdouble (2.0);126ucl_array_append (ar, cur);127cur = ucl_array_pop_last (ar);128assert (ucl_object_todouble (cur) == 2.0);129ucl_object_unref (cur);130cur = ucl_object_fromdouble (3.0);131ucl_array_prepend (ar, cur);132cur = ucl_array_pop_first (ar);133assert (ucl_object_todouble (cur) == 3.0);134ucl_object_unref (cur);135136ucl_object_insert_key (obj, ar, "key4", 0, false);137cur = ucl_object_frombool (true);138/* Ref object to test refcounts */139ref = ucl_object_ref (cur);140ucl_object_insert_key (obj, cur, "key4", 0, false);141/* Empty strings */142cur = ucl_object_fromstring_common (" ", 0, UCL_STRING_TRIM);143ucl_object_insert_key (obj, cur, "key5", 0, false);144cur = ucl_object_fromstring_common ("", 0, UCL_STRING_ESCAPE);145ucl_object_insert_key (obj, cur, "key6", 0, false);146cur = ucl_object_fromstring_common (" \n", 0, UCL_STRING_ESCAPE);147ucl_object_insert_key (obj, cur, "key7", 0, false);148/* Numbers and booleans */149cur = ucl_object_fromstring_common ("1mb", 0, UCL_STRING_ESCAPE | UCL_STRING_PARSE);150ucl_object_insert_key (obj, cur, "key8", 0, false);151cur = ucl_object_fromstring_common ("3.14", 0, UCL_STRING_PARSE);152ucl_object_insert_key (obj, cur, "key9", 0, false);153cur = ucl_object_fromstring_common ("true", 0, UCL_STRING_PARSE);154ucl_object_insert_key (obj, cur, "key10", 0, false);155cur = ucl_object_fromstring_common (" off ", 0, UCL_STRING_PARSE | UCL_STRING_TRIM);156ucl_object_insert_key (obj, cur, "key11", 0, false);157cur = ucl_object_fromstring_common ("[email protected]", 0, UCL_STRING_PARSE_INT);158ucl_object_insert_key (obj, cur, "key12", 0, false);159cur = ucl_object_fromstring_common ("#test", 0, UCL_STRING_PARSE_INT);160ucl_object_insert_key (obj, cur, "key13", 0, false);161cur = ucl_object_frombool (true);162ucl_object_insert_key (obj, cur, "k=3", 0, false);163ucl_object_insert_key (obj, ar1, "key14", 0, false);164cur = ucl_object_new_userdata (ud_dtor, ud_emit, NULL);165ucl_object_insert_key (obj, cur, "key15", 0, false);166167/* More tests for keys */168cur = ucl_object_fromlstring ("test", 3);169ucl_object_insert_key (obj, cur, "key16", 0, false);170test = ucl_object_lookup_any (obj, "key100", "key200", "key300", "key16", NULL);171assert (test == cur);172test = ucl_object_lookup_len (obj, "key160", 5);173assert (test == cur);174cur = ucl_object_pop_key (obj, "key16");175assert (test == cur);176test = ucl_object_pop_key (obj, "key16");177assert (test == NULL);178test = ucl_object_lookup_len (obj, "key160", 5);179assert (test == NULL);180/* Objects merging tests */181test_obj = ucl_object_new_full (UCL_OBJECT, 2);182ucl_object_insert_key (test_obj, cur, "key16", 0, true);183ucl_object_merge (obj, test_obj, true);184ucl_object_unref (test_obj);185/* Array merging test */186test_obj = ucl_object_new_full (UCL_ARRAY, 3);187ucl_array_append (test_obj, ucl_object_fromstring ("test"));188ucl_array_merge (test_obj, ar1, false);189ucl_object_insert_key (obj, test_obj, "key17", 0, true);190/* Object deletion */191cur = ucl_object_fromstring ("test");192ucl_object_insert_key (obj, cur, "key18", 0, true);193assert (ucl_object_delete_key (obj, "key18"));194assert (!ucl_object_delete_key (obj, "key18"));195cur = ucl_object_fromlstring ("test", 4);196ucl_object_insert_key (obj, cur, "key18\0\0", 7, true);197assert (ucl_object_lookup_len (obj, "key18\0\0", 7) == cur);198assert (ucl_object_lookup (obj, "key18") == NULL);199assert (ucl_object_lookup_len (obj, "key18\0\1", 7) == NULL);200assert (ucl_object_delete_keyl (obj, "key18\0\0", 7));201202/* Comments */203204comments = ucl_object_typed_new (UCL_OBJECT);205found = ucl_object_lookup (obj, "key17");206test = ucl_object_lookup (obj, "key16");207ucl_comments_add (comments, found, "# test comment");208assert (ucl_comments_find (comments, found) != NULL);209assert (ucl_comments_find (comments, test) == NULL);210ucl_comments_move (comments, found, test);211assert (ucl_comments_find (comments, found) == NULL);212assert (ucl_comments_find (comments, test) != NULL);213214/* Array replace */215ar1 = ucl_object_typed_new (UCL_ARRAY);216cur = ucl_object_fromstring ("test");217cur = ucl_elt_append (cur, ucl_object_fromstring ("test1"));218ucl_array_append (ar1, cur);219test = ucl_array_replace_index (ar1, ucl_object_fromstring ("test2"), 0);220assert (test == cur);221222/* Try to find using path */223/* Should exist */224found = ucl_object_lookup_path (obj, "key4.1");225assert (found != NULL && ucl_object_toint (found) == 10);226/* . should be ignored */227found = ucl_object_lookup_path (obj, ".key4.1");228assert (found != NULL && ucl_object_toint (found) == 10);229/* moar dots... */230found = ucl_object_lookup_path (obj, ".key4........1...");231assert (found != NULL && ucl_object_toint (found) == 10);232/* No such index */233found = ucl_object_lookup_path (obj, ".key4.3");234assert (found == NULL);235/* No such key */236found = ucl_object_lookup_path (obj, "key9..key1");237assert (found == NULL);238239/* Test iteration */240it = ucl_object_iterate_new (obj);241it_obj = ucl_object_iterate_safe (it, true);242assert (!ucl_object_iter_chk_excpn (it));243/* key0 = 0.1 */244assert (ucl_object_type (it_obj) == UCL_FLOAT);245it_obj = ucl_object_iterate_safe (it, true);246assert (!ucl_object_iter_chk_excpn (it));247/* key1 = "" */248assert (ucl_object_type (it_obj) == UCL_STRING);249it_obj = ucl_object_iterate_safe (it, true);250assert (!ucl_object_iter_chk_excpn (it));251/* key2 = "" */252assert (ucl_object_type (it_obj) == UCL_STRING);253it_obj = ucl_object_iterate_safe (it, true);254assert (!ucl_object_iter_chk_excpn (it));255/* key3 = "" */256assert (ucl_object_type (it_obj) == UCL_STRING);257it_obj = ucl_object_iterate_safe (it, true);258assert (!ucl_object_iter_chk_excpn (it));259/* key4 = ([float, int, float], boolean) */260ucl_object_iterate_reset (it, it_obj);261it_obj = ucl_object_iterate_safe (it, true);262assert (!ucl_object_iter_chk_excpn (it));263assert (ucl_object_type (it_obj) == UCL_FLOAT);264it_obj = ucl_object_iterate_safe (it, true);265assert (!ucl_object_iter_chk_excpn (it));266assert (ucl_object_type (it_obj) == UCL_INT);267it_obj = ucl_object_iterate_safe (it, true);268assert (!ucl_object_iter_chk_excpn (it));269assert (ucl_object_type (it_obj) == UCL_FLOAT);270it_obj = ucl_object_iterate_safe (it, true);271assert (!ucl_object_iter_chk_excpn (it));272assert (ucl_object_type (it_obj) == UCL_BOOLEAN);273ucl_object_iterate_free (it);274275fn = ucl_object_emit_memory_funcs ((void **)&emitted);276assert (ucl_object_emit_full (obj, UCL_EMIT_CONFIG, fn, comments));277fprintf (out, "%s\n", emitted);278ucl_object_emit_funcs_free (fn);279ucl_object_unref (obj);280ucl_object_unref (comments);281282parser = ucl_parser_new (UCL_PARSER_NO_IMPLICIT_ARRAYS);283284if (ucl_parser_add_chunk_full (parser, emitted, strlen (emitted),2853, UCL_DUPLICATE_ERROR, UCL_PARSE_UCL)) {286/* Should fail due to duplicate */287assert (0);288}289else {290assert (ucl_parser_get_error (parser) != NULL);291ucl_parser_clear_error (parser);292ucl_parser_free (parser);293parser = ucl_parser_new (0);294ucl_parser_add_chunk_full (parser, emitted, strlen (emitted),2953, UCL_DUPLICATE_MERGE, UCL_PARSE_UCL);296}297298assert (ucl_parser_get_column (parser) == 0);299assert (ucl_parser_get_linenum (parser) != 0);300ucl_parser_clear_error (parser);301assert (ucl_parser_get_error_code (parser) == 0);302obj = ucl_parser_get_object (parser);303ucl_parser_free (parser);304ucl_object_unref (obj);305306if (emitted != NULL) {307free (emitted);308}309fclose (out);310311/* Ref should still be accessible */312ref->value.iv = 100500;313ucl_object_unref (ref);314315return ret;316}317318319