VirtualBox

Changeset 61730 in vbox for trunk


Ignore:
Timestamp:
Jun 16, 2016 12:05:08 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
108109
Message:

Runtime/RTJson: Enhance testcase and two fixes

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/json.cpp

    r61721 r61730  
    14121412        if (pIt->idxCur < pThis->Type.Array.cItems)
    14131413            pIt->idxCur++;
    1414         else
     1414
     1415        if (pIt->idxCur == pThis->Type.Object.cMembers)
    14151416            rc = VERR_JSON_ITERATOR_END;
    14161417    }
     
    14211422        if (pIt->idxCur < pThis->Type.Object.cMembers)
    14221423            pIt->idxCur++;
    1423         else
     1424
     1425        if (pIt->idxCur == pThis->Type.Object.cMembers)
    14241426            rc = VERR_JSON_ITERATOR_END;
    14251427    }
  • trunk/src/VBox/Runtime/testcase/tstRTJson.cpp

    r61721 r61730  
    3030*********************************************************************************************************************************/
    3131#include <iprt/json.h>
    32 
     32#include <iprt/string.h>
    3333#include <iprt/test.h>
     34
     35static const char *g_pszJson =
     36    "{\n"
     37    "    \"number\": 100,\n"
     38    "    \"string\": \"test\",\n"
     39    "    \"array\": [1, 2, 3, 4, 5, \"6\"],\n"
     40    "    \"subobject\":\n"
     41    "        {\n"
     42    "            \"false\": false,\n"
     43    "            \"true\": true,\n"
     44    "            \"null\": null\n"
     45    "        }\n"
     46    "}\n";
    3447
    3548/**
     
    6982        int rc = RTJsonParseFromString(&hJsonVal, aTests[iTest].pszJson, NULL);
    7083        if (rc != aTests[iTest].iRcResult)
    71             RTTestIFailed("RTJsonParseFromString() for \"%s\" failed, expected %Rrc got %Rrc\n",
    72                           aTests[iTest].pszJson, aTests[iTest].iRcResult, rc);
     84            RTTestFailed(hTest, "RTJsonParseFromString() for \"%s\" failed, expected %Rrc got %Rrc\n",
     85                         aTests[iTest].pszJson, aTests[iTest].iRcResult, rc);
    7386        if (RT_SUCCESS(rc))
    7487        {
     
    7689                RTJsonValueRelease(hJsonVal);
    7790            else
    78                 RTTestIFailed("RTJsonParseFromString() returned success but no value\n");
     91                RTTestFailed(hTest, "RTJsonParseFromString() returned success but no value\n");
    7992        }
    8093        else if (hJsonVal != NIL_RTJSONVAL)
    81             RTTestIFailed("RTJsonParseFromString() failed but a JSON value was returned\n");
     94            RTTestFailed(hTest, "RTJsonParseFromString() failed but a JSON value was returned\n");
     95    }
     96}
     97
     98/**
     99 * Checks that methods not indended for the given type return the correct error.
     100 */
     101static void tstCorrectnessRcForInvalidType(RTTEST hTest, RTJSONVAL hJsonVal, RTJSONVALTYPE enmType)
     102{
     103#if 0 /* Enable manually or it will assert all over the place for debug builds. */
     104    if (   enmType != RTJSONVALTYPE_OBJECT
     105        && enmType != RTJSONVALTYPE_ARRAY)
     106    {
     107        /* The iterator API should return errors. */
     108        RTJSONIT hJsonIt = NIL_RTJSONIT;
     109        RTTEST_CHECK_RC(hTest, RTJsonIteratorBegin(hJsonVal, &hJsonIt), VERR_JSON_VALUE_INVALID_TYPE);
     110    }
     111
     112    if (enmType != RTJSONVALTYPE_ARRAY)
     113    {
     114        /* The Array access methods should return errors. */
     115        uint32_t cItems = 0;
     116        RTJSONVAL hJsonValItem = NIL_RTJSONVAL;
     117        RTTEST_CHECK(hTest, RTJsonValueGetArraySize(hJsonVal) == 0);
     118        RTTEST_CHECK_RC(hTest, RTJsonValueGetArraySizeEx(hJsonVal, &cItems), VERR_JSON_VALUE_INVALID_TYPE);
     119        RTTEST_CHECK_RC(hTest, RTJsonValueGetByIndex(hJsonVal, 0, &hJsonValItem), VERR_JSON_VALUE_INVALID_TYPE);
     120    }
     121
     122    if (enmType != RTJSONVALTYPE_OBJECT)
     123    {
     124        /* The object access methods should return errors. */
     125        RTJSONVAL hJsonValMember = NIL_RTJSONVAL;
     126        RTTEST_CHECK_RC(hTest, RTJsonValueGetByName(hJsonVal, "test", &hJsonValMember), VERR_JSON_VALUE_INVALID_TYPE);
     127    }
     128
     129    if (enmType != RTJSONVALTYPE_NUMBER)
     130    {
     131        int64_t i64Num = 0;
     132        RTTEST_CHECK_RC(hTest, RTJsonValueGetNumber(hJsonVal, &i64Num), VERR_JSON_VALUE_INVALID_TYPE);
     133    }
     134
     135    if (enmType != RTJSONVALTYPE_STRING)
     136    {
     137        const char *psz = NULL;
     138        RTTEST_CHECK(hTest, RTJsonValueGetString(hJsonVal) == NULL);
     139        RTTEST_CHECK_RC(hTest, RTJsonValueGetStringEx(hJsonVal, &psz), VERR_JSON_VALUE_INVALID_TYPE);
     140    }
     141#endif
     142}
     143
     144/**
     145 * Tests the array accessors.
     146 */
     147static void tstArray(RTTEST hTest, RTJSONVAL hJsonVal)
     148{
     149    uint32_t cItems = 0;
     150    RTTEST_CHECK(hTest, RTJsonValueGetArraySize(hJsonVal) == 6);
     151    RTTEST_CHECK_RC_OK(hTest, RTJsonValueGetArraySizeEx(hJsonVal, &cItems));
     152
     153    for (uint32_t i = 1; i <= 5; i++)
     154    {
     155        int64_t i64Num = 0;
     156        RTJSONVAL hJsonValItem = NIL_RTJSONVAL;
     157        RTTEST_CHECK_RC_OK_RETV(hTest, RTJsonValueGetByIndex(hJsonVal, i - 1, &hJsonValItem));
     158        RTTEST_CHECK(hTest, RTJsonValueGetType(hJsonValItem) == RTJSONVALTYPE_NUMBER);
     159        RTTEST_CHECK_RC_OK_RETV(hTest, RTJsonValueGetNumber(hJsonValItem, &i64Num));
     160        RTTEST_CHECK(hTest, i64Num == (int64_t)i);
     161        RTTEST_CHECK(hTest, RTJsonValueRelease(hJsonValItem) == 1);
     162    }
     163
     164    /* Last should be string. */
     165    const char *pszStr = NULL;
     166    RTJSONVAL hJsonValItem = NIL_RTJSONVAL;
     167    RTTEST_CHECK_RC_OK_RETV(hTest, RTJsonValueGetByIndex(hJsonVal, 5, &hJsonValItem));
     168    RTTEST_CHECK(hTest, RTJsonValueGetType(hJsonValItem) == RTJSONVALTYPE_STRING);
     169    RTTEST_CHECK_RC_OK_RETV(hTest, RTJsonValueGetStringEx(hJsonValItem, &pszStr));
     170    RTTEST_CHECK(hTest, RTJsonValueGetString(hJsonValItem) == pszStr);
     171    RTTEST_CHECK(hTest, strcmp(pszStr, "6") == 0);
     172    RTTEST_CHECK(hTest, RTJsonValueRelease(hJsonValItem) == 1);
     173}
     174
     175/**
     176 * Tests the iterator API for the given JSON array or object value.
     177 */
     178static void tstIterator(RTTEST hTest, RTJSONVAL hJsonVal)
     179{
     180    RTJSONIT hJsonIt = NIL_RTJSONIT;
     181    int rc = RTJsonIteratorBegin(hJsonVal, &hJsonIt);
     182    RTTEST_CHECK(hTest, RT_SUCCESS(rc));
     183    if (RT_SUCCESS(rc))
     184    {
     185        const char *pszName = NULL;
     186        RTJSONVAL hJsonValMember = NIL_RTJSONVAL;
     187        rc = RTJsonIteratorGetValue(hJsonIt, &hJsonValMember, &pszName);
     188        RTTEST_CHECK(hTest, RT_SUCCESS(rc));
     189        RTTEST_CHECK(hTest, pszName != NULL);
     190        RTTEST_CHECK(hTest, hJsonValMember != NIL_RTJSONVAL);
     191        while (RT_SUCCESS(rc))
     192        {
     193            RTJSONVALTYPE enmTypeMember = RTJsonValueGetType(hJsonValMember);
     194            tstCorrectnessRcForInvalidType(hTest, hJsonValMember, enmTypeMember);
     195
     196            switch (enmTypeMember)
     197            {
     198                case RTJSONVALTYPE_OBJECT:
     199                    RTTEST_CHECK(hTest, strcmp(pszName, "subobject") == 0);
     200                    tstIterator(hTest, hJsonValMember);
     201                    break;
     202                case RTJSONVALTYPE_ARRAY:
     203                    RTTEST_CHECK(hTest, strcmp(pszName, "array") == 0);
     204                    tstArray(hTest, hJsonValMember);
     205                    break;
     206                case RTJSONVALTYPE_STRING:
     207                {
     208                    RTTEST_CHECK(hTest, strcmp(pszName, "string") == 0);
     209                    const char *pszStr = NULL;
     210                    RTTEST_CHECK_RC_OK(hTest, RTJsonValueGetStringEx(hJsonValMember, &pszStr));
     211                    RTTEST_CHECK(hTest, strcmp(pszStr, "test") == 0);
     212                    break;
     213                }
     214                case RTJSONVALTYPE_NUMBER:
     215                {
     216                    RTTEST_CHECK(hTest, strcmp(pszName, "number") == 0);
     217                    int64_t i64Num = 0;
     218                    RTTEST_CHECK_RC_OK(hTest, RTJsonValueGetNumber(hJsonValMember, &i64Num));
     219                    RTTEST_CHECK(hTest, i64Num == 100);
     220                    break;
     221                }
     222                case RTJSONVALTYPE_NULL:
     223                    RTTEST_CHECK(hTest, strcmp(pszName, "null") == 0);
     224                    break;
     225                case RTJSONVALTYPE_TRUE:
     226                    RTTEST_CHECK(hTest, strcmp(pszName, "true") == 0);
     227                    break;
     228                case RTJSONVALTYPE_FALSE:
     229                    RTTEST_CHECK(hTest, strcmp(pszName, "false") == 0);
     230                    break;
     231                default:
     232                    RTTestFailed(hTest, "Invalid JSON value type %u returned\n", enmTypeMember);
     233            }
     234
     235            RTTEST_CHECK(hTest, RTJsonValueRelease(hJsonValMember) == 1);
     236            rc = RTJsonIteratorNext(hJsonIt);
     237            RTTEST_CHECK(hTest, rc == VINF_SUCCESS || rc == VERR_JSON_ITERATOR_END);
     238            if (RT_SUCCESS(rc))
     239                RTTEST_CHECK_RC_OK(hTest, RTJsonIteratorGetValue(hJsonIt, &hJsonValMember, &pszName));
     240        }
     241        RTJsonIteratorFree(hJsonIt);
    82242    }
    83243}
     
    88248static void tstCorrectness(RTTEST hTest)
    89249{
    90 
     250    RTTestSub(hTest, "Correctness");
     251
     252    RTJSONVAL hJsonVal = NIL_RTJSONVAL;
     253    RTTEST_CHECK_RC_OK_RETV(hTest, RTJsonParseFromString(&hJsonVal, g_pszJson, NULL));
     254
     255    if (hJsonVal != NIL_RTJSONVAL)
     256    {
     257        RTJSONVALTYPE enmType = RTJsonValueGetType(hJsonVal);
     258        if (enmType == RTJSONVALTYPE_OBJECT)
     259        {
     260            /* Excercise the other non object APIs to return VERR_JSON_VALUE_INVALID_TYPE. */
     261            tstCorrectnessRcForInvalidType(hTest, hJsonVal, enmType);
     262            tstIterator(hTest, hJsonVal);
     263        }
     264        else
     265            RTTestFailed(hTest, "RTJsonParseFromString() returned an invalid JSON value, expected OBJECT got %u\n", enmType);
     266        RTTEST_CHECK(hTest, RTJsonValueRelease(hJsonVal) == 0);
     267    }
     268    else
     269        RTTestFailed(hTest, "RTJsonParseFromString() returned success but no value\n");
    91270}
    92271
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette