mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Add KeyValue object.
This commit is contained in:
parent
2add6cef95
commit
b2a64b1f43
@ -42,11 +42,7 @@
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>String</code> object to simplify string handling.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>List</code> and <code>StringList</code> objects to simplify list handling.</p>
|
||||
<p>Add <code>Buffer</code>, <code>KeyValue</code>, <code>List</code>, <code>String</code>, <code>StringList</code>, <code>Variant</code>, and <code>VariantList</code> objects.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
@ -61,6 +57,10 @@
|
||||
<p>Minor changes to <code>Manifest</code> module, mostly for test reproducibility.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Improve <code>MemContext</code> module. Add temporary context blocks and refactor allocation arrays to include allocation size.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Replace <code>cfgCommandTotal()</code>/<code>cfgOptionTotal()</code> functions with constants. The constants are applicable in more cases and allow the compiler to optimize certain loops more efficiently.</p>
|
||||
</release-item>
|
||||
@ -72,18 +72,6 @@
|
||||
<release-item>
|
||||
<p>Refactor code to make valgrind happy.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Improve <code>MemContext</code> module. Add temporary context blocks and refactor allocation arrays to include allocation size.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>Buffer</code> object.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>Variant</code> and <code>VariantList</code> objects.</p>
|
||||
</release-item>
|
||||
</release-development-list>
|
||||
</release-core-list>
|
||||
|
||||
|
@ -7,6 +7,7 @@ pgbackrest: \
|
||||
common/errorType.o \
|
||||
common/memContext.o \
|
||||
common/type/buffer.o \
|
||||
common/type/keyValue.o \
|
||||
common/type/list.o \
|
||||
common/type/string.o \
|
||||
common/type/stringList.o \
|
||||
@ -22,6 +23,7 @@ pgbackrest: \
|
||||
common/errorType.o \
|
||||
common/memContext.o \
|
||||
common/type/buffer.o \
|
||||
common/type/keyValue.o \
|
||||
common/type/list.o \
|
||||
common/type/string.o \
|
||||
common/type/stringList.o \
|
||||
|
@ -14,6 +14,11 @@ Include NULL
|
||||
***********************************************************************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Include limits for data types
|
||||
***********************************************************************************************************************************/
|
||||
#include <limits.h>
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Define standard integer types for portability
|
||||
***********************************************************************************************************************************/
|
||||
@ -35,5 +40,7 @@ Include all header files in type directory for convenience
|
||||
#include "common/type/list.h"
|
||||
#include "common/type/string.h"
|
||||
#include "common/type/stringList.h"
|
||||
#include "common/type/variant.h"
|
||||
#include "common/type/variantList.h"
|
||||
|
||||
#endif
|
||||
|
255
src/common/type/keyValue.c
Normal file
255
src/common/type/keyValue.c
Normal file
@ -0,0 +1,255 @@
|
||||
/***********************************************************************************************************************************
|
||||
Key Value Handler
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/memContext.h"
|
||||
#include "common/type.h"
|
||||
#include "common/type/keyValue.h"
|
||||
#include "common/type/variantList.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constant to indicate key not found
|
||||
***********************************************************************************************************************************/
|
||||
#define KEY_NOT_FOUND UINT_MAX
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Contains information about the key value store
|
||||
***********************************************************************************************************************************/
|
||||
struct KeyValue
|
||||
{
|
||||
MemContext *memContext; // Mem context for the store
|
||||
List *list; // List of keys/values
|
||||
VariantList *keyList; // List of keys
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Contains information about an individual key/value pair
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct KeyValuePair
|
||||
{
|
||||
Variant *key; // The key
|
||||
Variant *value; // The value (this may be NULL)
|
||||
} KeyValuePair;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new key/value store
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *
|
||||
kvNew()
|
||||
{
|
||||
KeyValue *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("keyValue")
|
||||
{
|
||||
// Allocate state and set context
|
||||
this = memNew(sizeof(KeyValue));
|
||||
this->memContext = MEM_CONTEXT_NEW();
|
||||
|
||||
// Initialize list
|
||||
this->list = lstNew(sizeof(KeyValuePair));
|
||||
this->keyList = varLstNew();
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Duplicate key/value store
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *
|
||||
kvDup(const KeyValue *source)
|
||||
{
|
||||
KeyValue *this = kvNew();
|
||||
|
||||
// Duplicate all key/values
|
||||
for (unsigned int listIdx = 0; listIdx < lstSize(source->list); listIdx++)
|
||||
{
|
||||
const KeyValuePair *sourcePair = (const KeyValuePair *)lstGet(source->list, listIdx);
|
||||
|
||||
// Copy the pair
|
||||
KeyValuePair pair;
|
||||
pair.key = varDup(sourcePair->key);
|
||||
pair.value = varDup(sourcePair->value);
|
||||
|
||||
// Add to the list
|
||||
lstAdd(this->list, &pair);
|
||||
}
|
||||
|
||||
this->keyList = varLstDup(source->keyList);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get key index if it exists
|
||||
***********************************************************************************************************************************/
|
||||
static unsigned int
|
||||
kvGetIdx(const KeyValue *this, const Variant *key)
|
||||
{
|
||||
// Search for the key
|
||||
unsigned int listIdx = 0;
|
||||
|
||||
for (; listIdx < lstSize(this->list); listIdx++)
|
||||
{
|
||||
const KeyValuePair *pair = (const KeyValuePair *)lstGet(this->list, listIdx);
|
||||
|
||||
// Break if the key matches
|
||||
if (varEq(key, pair->key))
|
||||
break;
|
||||
}
|
||||
|
||||
// If key was not found
|
||||
if (listIdx == lstSize(this->list))
|
||||
return KEY_NOT_FOUND;
|
||||
|
||||
return listIdx;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get list of keys
|
||||
***********************************************************************************************************************************/
|
||||
const VariantList *
|
||||
kvKeyList(const KeyValue *this)
|
||||
{
|
||||
return this->keyList;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Internal put key/value pair
|
||||
|
||||
Handles the common logic for the external put functions. The correct mem context should be set before calling this function.
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
kvPutInternal(KeyValue *this, const Variant *key, Variant *value)
|
||||
{
|
||||
// Find the key
|
||||
unsigned int listIdx = kvGetIdx(this, key);
|
||||
|
||||
// If the key was not found then add it
|
||||
if (listIdx == KEY_NOT_FOUND)
|
||||
{
|
||||
// Copy the pair
|
||||
KeyValuePair pair;
|
||||
pair.key = varDup(key);
|
||||
pair.value = value;
|
||||
|
||||
// Add to the list
|
||||
lstAdd(this->list, &pair);
|
||||
|
||||
// Add to the key list
|
||||
varLstAdd(this->keyList, varDup(key));
|
||||
}
|
||||
// Else update it
|
||||
else
|
||||
{
|
||||
KeyValuePair *pair = (KeyValuePair *)lstGet(this->list, listIdx);
|
||||
|
||||
if (pair->value != NULL)
|
||||
varFree(pair->value);
|
||||
|
||||
pair->value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Put key/value pair
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *
|
||||
kvPut(KeyValue *this, const Variant *key, const Variant *value)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
kvPutInternal(this, key, varDup(value));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Add value to key -- if the key does not exist then this works the same as kvPut()
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *
|
||||
kvAdd(KeyValue *this, const Variant *key, const Variant *value)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
// Find the key
|
||||
unsigned int listIdx = kvGetIdx(this, key);
|
||||
|
||||
// If the key was not found then add it
|
||||
if (listIdx == KEY_NOT_FOUND)
|
||||
{
|
||||
kvPutInternal(this, key, varDup(value));
|
||||
}
|
||||
// Else create or add to the variant list
|
||||
else
|
||||
{
|
||||
KeyValuePair *pair = (KeyValuePair *)lstGet(this->list, listIdx);
|
||||
|
||||
if (pair->value == NULL)
|
||||
pair->value = varDup(value);
|
||||
else if (varType(pair->value) != varTypeVariantList)
|
||||
{
|
||||
Variant *valueList = varNewVarLstEmpty();
|
||||
varLstAdd(varVarLst(valueList), pair->value);
|
||||
varLstAdd(varVarLst(valueList), varDup(value));
|
||||
pair->value = valueList;
|
||||
}
|
||||
else
|
||||
varLstAdd(varVarLst(pair->value), varDup(value));
|
||||
}
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Put key/value store
|
||||
|
||||
If this is called on an existing key it will replace the key with an empty kev/value store, even if the key already contains a
|
||||
key/value store.
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *
|
||||
kvPutKv(KeyValue *this, const Variant *key)
|
||||
{
|
||||
KeyValue *result = NULL;
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
Variant *keyValue = varNewKv();
|
||||
result = varKv(keyValue);
|
||||
|
||||
kvPutInternal(this, key, keyValue);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get a value using the key
|
||||
***********************************************************************************************************************************/
|
||||
const Variant *
|
||||
kvGet(const KeyValue *this, const Variant *key)
|
||||
{
|
||||
Variant *result = NULL;
|
||||
|
||||
// Find the key
|
||||
unsigned int listIdx = kvGetIdx(this, key);
|
||||
|
||||
if (listIdx != KEY_NOT_FOUND)
|
||||
result = ((KeyValuePair *)lstGet(this->list, listIdx))->value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the string
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
kvFree(KeyValue *this)
|
||||
{
|
||||
memContextFree(this->memContext);
|
||||
}
|
26
src/common/type/keyValue.h
Normal file
26
src/common/type/keyValue.h
Normal file
@ -0,0 +1,26 @@
|
||||
/***********************************************************************************************************************************
|
||||
Key Value Handler
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef COMMON_TYPE_KEYVALUE_H
|
||||
#define COMMON_TYPE_KEYVALUE_H
|
||||
|
||||
#include "common/type/variant.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Key value object
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct KeyValue KeyValue;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *kvNew();
|
||||
KeyValue *kvDup(const KeyValue *source);
|
||||
KeyValue *kvAdd(KeyValue *this, const Variant *key, const Variant *value);
|
||||
const VariantList *kvKeyList(const KeyValue *this);
|
||||
KeyValue *kvPut(KeyValue *this, const Variant *key, const Variant *value);
|
||||
KeyValue *kvPutKv(KeyValue *this, const Variant *key);
|
||||
const Variant *kvGet(const KeyValue *this, const Variant *key);
|
||||
void kvFree(KeyValue *this);
|
||||
|
||||
#endif
|
@ -88,6 +88,13 @@ varDup(const Variant *this)
|
||||
break;
|
||||
}
|
||||
|
||||
case varTypeKeyValue:
|
||||
{
|
||||
KeyValue *data = kvDup(varKv(this));
|
||||
result = varNewInternal(varTypeKeyValue, (void *)&data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
|
||||
case varTypeString:
|
||||
{
|
||||
result = varNewStr(varStr(this));
|
||||
@ -336,6 +343,38 @@ varInt(const Variant *this)
|
||||
return *((int *)varData(this));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
New key/value variant
|
||||
***********************************************************************************************************************************/
|
||||
Variant *
|
||||
varNewKv()
|
||||
{
|
||||
// Create the variant
|
||||
KeyValue *data = kvNew();
|
||||
return varNewInternal(varTypeKeyValue, (void *)&data, sizeof(data));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Return key/value
|
||||
***********************************************************************************************************************************/
|
||||
KeyValue *
|
||||
varKv(const Variant *this)
|
||||
{
|
||||
KeyValue *result = NULL;
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
// Only valid for key/value
|
||||
if (this->type != varTypeKeyValue)
|
||||
THROW(AssertError, "variant type is not 'KeyValue'");
|
||||
|
||||
// Get the string
|
||||
result = *((KeyValue **)varData(this));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Return int regardless of variant type
|
||||
***********************************************************************************************************************************/
|
||||
@ -481,6 +520,12 @@ varFree(Variant *this)
|
||||
{
|
||||
switch (this->type)
|
||||
{
|
||||
case varTypeKeyValue:
|
||||
{
|
||||
kvFree(varKv(this));
|
||||
break;
|
||||
}
|
||||
|
||||
case varTypeString:
|
||||
{
|
||||
strFree(varStr(this));
|
||||
|
@ -27,6 +27,7 @@ typedef struct Variant Variant;
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/type/keyValue.h"
|
||||
#include "common/type/string.h"
|
||||
#include "common/type/variantList.h"
|
||||
|
||||
@ -42,6 +43,9 @@ Variant *varNewInt(int data);
|
||||
int varInt(const Variant *this);
|
||||
int varIntForce(const Variant *this);
|
||||
|
||||
Variant *varNewKv();
|
||||
KeyValue *varKv(const Variant *this);
|
||||
|
||||
Variant *varNewStr(const String *data);
|
||||
Variant *varNewStrZ(const char *data);
|
||||
String *varStr(const Variant *this);
|
||||
|
@ -173,7 +173,7 @@ my $oTestDef =
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'type-variant',
|
||||
&TESTDEF_TOTAL => 5,
|
||||
&TESTDEF_TOTAL => 6,
|
||||
&TESTDEF_C => true,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
@ -191,6 +191,16 @@ my $oTestDef =
|
||||
'common/type/variantList' => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'type-key-value',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_C => true,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
'common/type/keyValue' => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'encode',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
|
91
test/src/module/common/typeKeyValueTest.c
Normal file
91
test/src/module/common/typeKeyValueTest.c
Normal file
@ -0,0 +1,91 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Key Value Data Type
|
||||
***********************************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
***********************************************************************************************************************************/
|
||||
void testRun()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("kvNew() and kvFree()"))
|
||||
{
|
||||
KeyValue *store = NULL;
|
||||
|
||||
TEST_ASSIGN(store, kvNew(), "new store");
|
||||
TEST_RESULT_PTR_NE(store->memContext, NULL, "mem context set");
|
||||
TEST_RESULT_PTR_NE(store->list, NULL, "list set");
|
||||
TEST_RESULT_INT(lstSize(store->list), 0, "list empty");
|
||||
|
||||
TEST_RESULT_VOID(kvFree(store), "free store");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("kvPut(), kvAdd(), kvKeyList(), kvGet(), and kvDup()"))
|
||||
{
|
||||
KeyValue *store = NULL;
|
||||
|
||||
TEST_ASSIGN(store, kvNew(), "new store");
|
||||
|
||||
// Set various data types
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_PTR(kvPut(store, varNewStr(strNew("str-key")), varNewStr(strNew("str-value"))), store, "put string/string");
|
||||
TEST_RESULT_PTR(kvPut(store, varNewInt(42), varNewInt(57)), store, "put int/int");
|
||||
TEST_RESULT_PTR(kvPut(store, varNewStr(strNew("str-key-int")), varNewInt(99)), store, "put string/int");
|
||||
TEST_RESULT_PTR(kvPut(store, varNewInt(78), NULL), store, "put int/null");
|
||||
|
||||
// Get the types and make sure they have the correct value
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_STR(strPtr(varStr(kvGet(store, varNewStr(strNew("str-key"))))), "str-value", "get string/string");
|
||||
TEST_RESULT_INT(varInt(kvGet(store, varNewInt(42))), 57, "get int/int");
|
||||
TEST_RESULT_INT(varInt(kvGet(store, varNewStr(strNew("str-key-int")))), 99, "get string/int");
|
||||
TEST_RESULT_PTR(kvGet(store, varNewInt(78)), NULL, "get int/null");
|
||||
|
||||
// Check that a null value can be changed to non-null
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_PTR(kvPut(store, varNewInt(78), varNewInt(66)), store, "update int/null to int/int");
|
||||
TEST_RESULT_INT(varInt(kvGet(store, varNewInt(78))), 66, "get int/int");
|
||||
|
||||
// Check that a value can be changed
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_PTR(kvPut(store, varNewInt(78), varNewBool(false)), store, "update int/int to int/bool");
|
||||
TEST_RESULT_INT(varBool(kvGet(store, varNewInt(78))), false, "get int/bool");
|
||||
|
||||
// Use add to create variant list
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_PTR(kvAdd(store, varNewInt(99), NULL), store, "add int/null");
|
||||
TEST_RESULT_PTR(kvAdd(store, varNewInt(99), varNewInt(1)), store, "add int/int");
|
||||
TEST_RESULT_PTR(kvAdd(store, varNewInt(99), varNewInt(2)), store, "add int/int");
|
||||
TEST_RESULT_PTR(kvAdd(store, varNewInt(99), varNewInt(3)), store, "add int/int");
|
||||
|
||||
TEST_RESULT_INT(varInt(varLstGet(varVarLst(kvGet(store, varNewInt(99))), 0)), 1, "get int/int");
|
||||
TEST_RESULT_INT(varInt(varLstGet(varVarLst(kvGet(store, varNewInt(99))), 1)), 2, "get int/int");
|
||||
TEST_RESULT_INT(varInt(varLstGet(varVarLst(kvGet(store, varNewInt(99))), 2)), 3, "get int/int");
|
||||
|
||||
// Check item in key list
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_INT(varInt(varLstGet(kvKeyList(store), 1)), 42, "key list");
|
||||
|
||||
// Create a new kv and add it to this kv
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
KeyValue *storeSub = kvPutKv(store, varNewStr(strNew("kv-key")));
|
||||
|
||||
kvPut(storeSub, varNewStr(strNew("str-sub-key")), varNewStr(strNew("str-sub-value")));
|
||||
TEST_RESULT_STR(
|
||||
strPtr(varStr(kvGet(varKv(kvGet(store, varNewStr(strNew("kv-key")))), varNewStr(strNew("str-sub-key"))))),
|
||||
"str-sub-value", "get string/kv");
|
||||
|
||||
// Duplicate the kv
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
KeyValue *storeDup = kvDup(store);
|
||||
|
||||
TEST_RESULT_INT(varBool(kvGet(store, varNewInt(78))), false, "get int/bool");
|
||||
TEST_RESULT_INT(varInt(varLstGet(varVarLst(kvGet(store, varNewInt(99))), 2)), 3, "get int/int");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(varStr(kvGet(varKv(kvGet(storeDup, varNewStr(strNew("kv-key")))), varNewStr(strNew("str-sub-key"))))),
|
||||
"str-sub-value", "get string/kv");
|
||||
|
||||
TEST_RESULT_VOID(kvFree(storeDup), "free dup store");
|
||||
TEST_RESULT_VOID(kvFree(store), "free store");
|
||||
}
|
||||
}
|
@ -106,6 +106,31 @@ void testRun()
|
||||
TEST_RESULT_BOOL(varEq(varNewInt(444), varNewInt(123)), false, "int, int not eq");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("keyValue"))
|
||||
{
|
||||
TEST_ERROR(varKv(varNewInt(66)), AssertError, "variant type is not 'KeyValue'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Variant *keyValue = NULL;
|
||||
|
||||
TEST_ASSIGN(keyValue, varNewKv(), "new");
|
||||
TEST_RESULT_PTR(kvPut(varKv(keyValue), varNewInt(44), varNewInt(55)), varKv(keyValue), " put int/int");
|
||||
TEST_RESULT_INT(varInt(kvGet(varKv(keyValue), varNewInt(44))), 55, " get int/int");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Variant *keyValueDup = NULL;
|
||||
|
||||
TEST_ASSIGN(keyValueDup, varDup(keyValue), "duplicate");
|
||||
TEST_RESULT_INT(varInt(kvGet(varKv(keyValueDup), varNewInt(44))), 55, " get int/int");
|
||||
|
||||
varFree(keyValue);
|
||||
varFree(keyValueDup);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varEq(varNewKv(), varNewKv()), AssertError, "unable to test equality for KeyValue");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("String"))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user