Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "IDBBindingUtilities.h"
     28 #include "IDBKey.h"
     29 #include "IDBKeyPath.h"
     30 #include "SerializedScriptValue.h"
     31 
     32 #include <gtest/gtest.h>
     33 #include <wtf/Vector.h>
     34 
     35 #if ENABLE(INDEXED_DATABASE)
     36 
     37 using namespace WebCore;
     38 
     39 namespace {
     40 
     41 class LocalContext {
     42 public:
     43     LocalContext()
     44         : m_context(v8::Context::New())
     45     {
     46         m_context->Enter();
     47     }
     48 
     49     virtual ~LocalContext()
     50     {
     51         m_context->Exit();
     52         m_context.Dispose();
     53     }
     54 
     55 private:
     56     v8::HandleScope m_scope;
     57     v8::Persistent<v8::Context> m_context;
     58 };
     59 
     60 PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(SerializedScriptValue* value, const String& keyPath)
     61 {
     62     Vector<IDBKeyPathElement> idbKeyPath;
     63     IDBKeyPathParseError parseError;
     64     IDBParseKeyPath(keyPath, idbKeyPath, parseError);
     65     EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
     66     return createIDBKeyFromSerializedValueAndKeyPath(value, idbKeyPath);
     67 }
     68 
     69 void checkKeyPathNullValue(SerializedScriptValue* value, const String& keyPath)
     70 {
     71     RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
     72     ASSERT_FALSE(idbKey.get());
     73 }
     74 
     75 PassRefPtr<SerializedScriptValue> injectKey(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
     76 {
     77     Vector<IDBKeyPathElement> idbKeyPath;
     78     IDBKeyPathParseError parseError;
     79     IDBParseKeyPath(keyPath, idbKeyPath, parseError);
     80     EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
     81     return injectIDBKeyIntoSerializedValue(key, value, idbKeyPath);
     82 }
     83 
     84 void checkInjection(PassRefPtr<IDBKey> prpKey, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
     85 {
     86     RefPtr<IDBKey> key = prpKey;
     87     RefPtr<SerializedScriptValue> newValue = injectKey(key, value, keyPath);
     88     ASSERT_TRUE(newValue);
     89     RefPtr<IDBKey> extractedKey = checkKeyFromValueAndKeyPathInternal(newValue.get(), keyPath);
     90     EXPECT_TRUE(key->isEqual(extractedKey.get()));
     91 }
     92 
     93 void checkInjectionFails(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
     94 {
     95     EXPECT_FALSE(injectKey(key, value, keyPath));
     96 }
     97 
     98 void checkKeyPathStringValue(SerializedScriptValue* value, const String& keyPath, const String& expected)
     99 {
    100     RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
    101     ASSERT_TRUE(idbKey.get());
    102     ASSERT_EQ(IDBKey::StringType, idbKey->type());
    103     ASSERT_TRUE(expected == idbKey->string());
    104 }
    105 
    106 void checkKeyPathNumberValue(SerializedScriptValue* value, const String& keyPath, int expected)
    107 {
    108     RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
    109     ASSERT_TRUE(idbKey.get());
    110     ASSERT_EQ(IDBKey::NumberType, idbKey->type());
    111     ASSERT_TRUE(expected == idbKey->number());
    112 }
    113 
    114 TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue)
    115 {
    116     LocalContext v8context;
    117     v8::Local<v8::Object> object = v8::Object::New();
    118     object->Set(v8::String::New("foo"), v8::String::New("zoo"));
    119 
    120     RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
    121 
    122     checkKeyPathStringValue(serializedScriptValue.get(), "foo", "zoo");
    123     checkKeyPathNullValue(serializedScriptValue.get(), "bar");
    124     checkKeyPathNullValue(serializedScriptValue.get(), "[3]");
    125 }
    126 
    127 TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyNumberValue)
    128 {
    129     LocalContext v8context;
    130     v8::Local<v8::Object> object = v8::Object::New();
    131     object->Set(v8::String::New("foo"), v8::Number::New(456));
    132 
    133     RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
    134 
    135     checkKeyPathNumberValue(serializedScriptValue.get(), "foo", 456);
    136     checkKeyPathNullValue(serializedScriptValue.get(), "bar");
    137     checkKeyPathNullValue(serializedScriptValue.get(), "[3]");
    138 }
    139 
    140 TEST(IDBKeyFromValueAndKeyPathTest, TopLevelArrayElement)
    141 {
    142     LocalContext v8context;
    143     v8::Local<v8::Array> array = v8::Array::New();
    144     array->Set(3, v8::String::New("zoo"));
    145 
    146     RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(array);
    147 
    148     checkKeyPathStringValue(serializedScriptValue.get(), "[3]", "zoo");
    149     checkKeyPathNullValue(serializedScriptValue.get(), "foo");
    150     checkKeyPathNullValue(serializedScriptValue.get(), "bar");
    151 }
    152 
    153 TEST(IDBKeyFromValueAndKeyPathTest, SubProperty)
    154 {
    155     LocalContext v8context;
    156     v8::Local<v8::Object> object = v8::Object::New();
    157     v8::Local<v8::Object> subProperty = v8::Object::New();
    158     subProperty->Set(v8::String::New("bar"), v8::String::New("zee"));
    159     object->Set(v8::String::New("foo"), subProperty);
    160 
    161     RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
    162 
    163     checkKeyPathStringValue(serializedScriptValue.get(), "foo.bar", "zee");
    164     checkKeyPathNullValue(serializedScriptValue.get(), "bar");
    165     checkKeyPathNullValue(serializedScriptValue.get(), "[3]");
    166 }
    167 
    168 TEST(IDBKeyFromValueAndKeyPathTest, Array2D)
    169 {
    170     LocalContext v8context;
    171     v8::Local<v8::Object> object = v8::Object::New();
    172     v8::Local<v8::Array> array = v8::Array::New();
    173     v8::Local<v8::Array> subArray = v8::Array::New();
    174     subArray->Set(7, v8::String::New("zee"));
    175     array->Set(3, subArray);
    176     object->Set(v8::String::New("foo"), array);
    177 
    178     RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
    179 
    180     checkKeyPathStringValue(serializedScriptValue.get(), "foo[3][7]", "zee");
    181     checkKeyPathNullValue(serializedScriptValue.get(), "bar");
    182     checkKeyPathNullValue(serializedScriptValue.get(), "[4]");
    183 }
    184 
    185 TEST(InjectIDBKeyTest, TopLevelPropertyStringValue)
    186 {
    187     LocalContext v8context;
    188     v8::Local<v8::Object> object = v8::Object::New();
    189     object->Set(v8::String::New("foo"), v8::String::New("zoo"));
    190 
    191     checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "bar");
    192     checkInjection(IDBKey::createNumber(1234), SerializedScriptValue::create(object), "bar");
    193 
    194     checkInjectionFails(IDBKey::createString("key"), SerializedScriptValue::create(object), "foo.bar");
    195     checkInjectionFails(IDBKey::createString("key"), SerializedScriptValue::create(object), "[3]");
    196 }
    197 
    198 TEST(InjectIDBKeyTest, TopLevelArrayElement)
    199 {
    200     LocalContext v8context;
    201     v8::Local<v8::Array> array = v8::Array::New();
    202     array->Set(3, v8::String::New("zoo"));
    203 
    204     checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(array), "[2]");
    205     checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(array), "[4]");
    206     checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(array), "[1]");
    207 
    208     checkInjectionFails(IDBKey::createString("foo"), SerializedScriptValue::create(array), "[5].bar");
    209 }
    210 
    211 TEST(InjectIDBKeyTest, SubProperty)
    212 {
    213     LocalContext v8context;
    214     v8::Local<v8::Object> object = v8::Object::New();
    215     v8::Local<v8::Object> subProperty = v8::Object::New();
    216     subProperty->Set(v8::String::New("bar"), v8::String::New("zee"));
    217     object->Set(v8::String::New("foo"), subProperty);
    218 
    219     checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo.baz");
    220     checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(object), "foo.baz");
    221     checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "foo.baz");
    222     checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "bar");
    223 
    224     checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo.bar.baz");
    225     checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo.xyz.foo");
    226 }
    227 
    228 TEST(InjectIDBKeyTest, Array2D)
    229 {
    230     LocalContext v8context;
    231     v8::Local<v8::Object> object = v8::Object::New();
    232     v8::Local<v8::Array> array = v8::Array::New();
    233     v8::Local<v8::Array> subArray = v8::Array::New();
    234     subArray->Set(7, v8::String::New("zee"));
    235     array->Set(3, subArray);
    236     object->Set(v8::String::New("foo"), array);
    237 
    238     checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo[3][8]");
    239     checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(object), "foo[3][8]");
    240     checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "foo[3][8]");
    241     checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "bar");
    242     checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo[4]");
    243 
    244     checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo[3][7].foo");
    245 }
    246 } // namespace
    247 
    248 #endif // ENABLE(INDEXED_DATABASE)
    249