1 /* 2 * Copyright (C) 2011 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 "bindings/v8/IDBBindingUtilities.h" 28 29 #include "bindings/v8/V8Binding.h" 30 #include "bindings/v8/V8PerIsolateData.h" 31 #include "bindings/v8/V8Utilities.h" 32 #include "modules/indexeddb/IDBKey.h" 33 #include "modules/indexeddb/IDBKeyPath.h" 34 35 #include <gtest/gtest.h> 36 37 using namespace WebCore; 38 39 namespace { 40 41 PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(const ScriptValue& value, const String& keyPath) 42 { 43 IDBKeyPath idbKeyPath(keyPath); 44 EXPECT_TRUE(idbKeyPath.isValid()); 45 46 return createIDBKeyFromScriptValueAndKeyPath(0, value, idbKeyPath); 47 } 48 49 void checkKeyPathNullValue(const ScriptValue& value, const String& keyPath) 50 { 51 RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath); 52 ASSERT_FALSE(idbKey.get()); 53 } 54 55 bool injectKey(PassRefPtr<IDBKey> key, ScriptValue& value, const String& keyPath) 56 { 57 IDBKeyPath idbKeyPath(keyPath); 58 EXPECT_TRUE(idbKeyPath.isValid()); 59 return injectIDBKeyIntoScriptValue(0, key, value, idbKeyPath); 60 } 61 62 void checkInjection(PassRefPtr<IDBKey> prpKey, ScriptValue& value, const String& keyPath) 63 { 64 RefPtr<IDBKey> key = prpKey; 65 bool result = injectKey(key, value, keyPath); 66 ASSERT_TRUE(result); 67 RefPtr<IDBKey> extractedKey = checkKeyFromValueAndKeyPathInternal(value, keyPath); 68 EXPECT_TRUE(key->isEqual(extractedKey.get())); 69 } 70 71 void checkInjectionFails(PassRefPtr<IDBKey> key, ScriptValue& value, const String& keyPath) 72 { 73 EXPECT_FALSE(injectKey(key, value, keyPath)); 74 } 75 76 void checkKeyPathStringValue(const ScriptValue& value, const String& keyPath, const String& expected) 77 { 78 RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath); 79 ASSERT_TRUE(idbKey.get()); 80 ASSERT_EQ(IDBKey::StringType, idbKey->type()); 81 ASSERT_TRUE(expected == idbKey->string()); 82 } 83 84 void checkKeyPathNumberValue(const ScriptValue& value, const String& keyPath, int expected) 85 { 86 RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath); 87 ASSERT_TRUE(idbKey.get()); 88 ASSERT_EQ(IDBKey::NumberType, idbKey->type()); 89 ASSERT_TRUE(expected == idbKey->number()); 90 } 91 92 class IDBKeyFromValueAndKeyPathTest : public testing::Test { 93 public: 94 IDBKeyFromValueAndKeyPathTest() 95 : m_handleScope(v8::Isolate::GetCurrent()) 96 , m_scope(v8::Context::New(v8::Isolate::GetCurrent())) 97 { 98 } 99 100 private: 101 v8::HandleScope m_handleScope; 102 v8::Context::Scope m_scope; 103 }; 104 105 TEST_F(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue) 106 { 107 v8::Local<v8::Object> object = v8::Object::New(); 108 object->Set(v8::String::New("foo"), v8::String::New("zoo")); 109 110 ScriptValue scriptValue(object); 111 112 checkKeyPathStringValue(scriptValue, "foo", "zoo"); 113 checkKeyPathNullValue(scriptValue, "bar"); 114 } 115 116 TEST_F(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyNumberValue) 117 { 118 v8::Local<v8::Object> object = v8::Object::New(); 119 object->Set(v8::String::New("foo"), v8::Number::New(456)); 120 121 ScriptValue scriptValue(object); 122 123 checkKeyPathNumberValue(scriptValue, "foo", 456); 124 checkKeyPathNullValue(scriptValue, "bar"); 125 } 126 127 TEST_F(IDBKeyFromValueAndKeyPathTest, SubProperty) 128 { 129 v8::Local<v8::Object> object = v8::Object::New(); 130 v8::Local<v8::Object> subProperty = v8::Object::New(); 131 subProperty->Set(v8::String::New("bar"), v8::String::New("zee")); 132 object->Set(v8::String::New("foo"), subProperty); 133 134 ScriptValue scriptValue(object); 135 136 checkKeyPathStringValue(scriptValue, "foo.bar", "zee"); 137 checkKeyPathNullValue(scriptValue, "bar"); 138 } 139 140 class InjectIDBKeyTest : public IDBKeyFromValueAndKeyPathTest { 141 }; 142 143 TEST_F(InjectIDBKeyTest, TopLevelPropertyStringValue) 144 { 145 v8::Local<v8::Object> object = v8::Object::New(); 146 object->Set(v8::String::New("foo"), v8::String::New("zoo")); 147 148 ScriptValue foozoo(object); 149 checkInjection(IDBKey::createString("myNewKey"), foozoo, "bar"); 150 checkInjection(IDBKey::createNumber(1234), foozoo, "bar"); 151 152 checkInjectionFails(IDBKey::createString("key"), foozoo, "foo.bar"); 153 } 154 155 TEST_F(InjectIDBKeyTest, SubProperty) 156 { 157 v8::Local<v8::Object> object = v8::Object::New(); 158 v8::Local<v8::Object> subProperty = v8::Object::New(); 159 subProperty->Set(v8::String::New("bar"), v8::String::New("zee")); 160 object->Set(v8::String::New("foo"), subProperty); 161 162 ScriptValue scriptObject(object); 163 checkInjection(IDBKey::createString("myNewKey"), scriptObject, "foo.baz"); 164 checkInjection(IDBKey::createNumber(789), scriptObject, "foo.baz"); 165 checkInjection(IDBKey::createDate(4567), scriptObject, "foo.baz"); 166 checkInjection(IDBKey::createDate(4567), scriptObject, "bar"); 167 checkInjection(IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "foo.baz"); 168 checkInjection(IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "bar"); 169 170 checkInjectionFails(IDBKey::createString("zoo"), scriptObject, "foo.bar.baz"); 171 checkInjection(IDBKey::createString("zoo"), scriptObject, "foo.xyz.foo"); 172 } 173 174 } // namespace 175