Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: test/unittests/value-serializer-unittest.cc

Issue 2232243003: Blink-compatible serialization of oddball values. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add comments explaining varints. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/unittests/unittests.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/value-serializer.h"
6 #include "include/v8.h"
7 #include "src/api.h"
8 #include "test/unittests/test-utils.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace v8 {
12 namespace {
13
14 class ValueSerializerTest : public TestWithIsolate {
15 protected:
16 ValueSerializerTest()
17 : serialization_context_(Context::New(isolate())),
18 deserialization_context_(Context::New(isolate())) {}
19
20 const Local<Context>& serialization_context() {
21 return serialization_context_;
22 }
23 const Local<Context>& deserialization_context() {
24 return deserialization_context_;
25 }
26
27 template <typename InputFunctor, typename OutputFunctor>
28 void RoundTripTest(const InputFunctor& input_functor,
29 const OutputFunctor& output_functor) {
30 std::vector<uint8_t> data;
31 {
32 Context::Scope scope(serialization_context());
33 TryCatch try_catch(isolate());
34 // TODO(jbroman): Use the public API once it exists.
35 Local<Value> input_value = input_functor();
36 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate());
37 i::HandleScope handle_scope(internal_isolate);
38 i::ValueSerializer serializer;
39 serializer.WriteHeader();
40 ASSERT_TRUE(serializer.WriteObject(Utils::OpenHandle(*input_value))
41 .FromMaybe(false));
42 ASSERT_FALSE(try_catch.HasCaught());
43 data = serializer.ReleaseBuffer();
44 }
45 DecodeTest(data, output_functor);
46 }
47
48 template <typename OutputFunctor>
49 void DecodeTest(const std::vector<uint8_t>& data,
50 const OutputFunctor& output_functor) {
51 Context::Scope scope(deserialization_context());
52 TryCatch try_catch(isolate());
53 // TODO(jbroman): Use the public API once it exists.
54 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate());
55 i::HandleScope handle_scope(internal_isolate);
56 i::ValueDeserializer deserializer(
57 internal_isolate,
58 i::Vector<const uint8_t>(&data[0], static_cast<int>(data.size())));
59 ASSERT_TRUE(deserializer.ReadHeader().FromMaybe(false));
60 Local<Value> result;
61 ASSERT_TRUE(ToLocal<Value>(deserializer.ReadObject(), &result));
62 ASSERT_FALSE(result.IsEmpty());
63 ASSERT_FALSE(try_catch.HasCaught());
64 ASSERT_TRUE(deserialization_context()
65 ->Global()
66 ->CreateDataProperty(deserialization_context_,
67 StringFromUtf8("result"), result)
68 .FromMaybe(false));
69 output_functor(result);
70 ASSERT_FALSE(try_catch.HasCaught());
71 }
72
73 void InvalidDecodeTest(const std::vector<uint8_t>& data) {
74 Context::Scope scope(deserialization_context());
75 TryCatch try_catch(isolate());
76 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate());
77 i::HandleScope handle_scope(internal_isolate);
78 i::ValueDeserializer deserializer(
79 internal_isolate,
80 i::Vector<const uint8_t>(&data[0], static_cast<int>(data.size())));
81 Maybe<bool> header_result = deserializer.ReadHeader();
82 if (header_result.IsNothing()) return;
83 ASSERT_TRUE(header_result.ToChecked());
84 ASSERT_TRUE(deserializer.ReadObject().is_null());
85 }
86
87 Local<Value> EvaluateScriptForInput(const char* utf8_source) {
88 Local<String> source = StringFromUtf8(utf8_source);
89 Local<Script> script =
90 Script::Compile(serialization_context_, source).ToLocalChecked();
91 return script->Run(serialization_context_).ToLocalChecked();
92 }
93
94 bool EvaluateScriptForResultBool(const char* utf8_source) {
95 Local<String> source = StringFromUtf8(utf8_source);
96 Local<Script> script =
97 Script::Compile(deserialization_context_, source).ToLocalChecked();
98 Local<Value> value = script->Run(deserialization_context_).ToLocalChecked();
99 return value->BooleanValue(deserialization_context_).FromJust();
100 }
101
102 Local<String> StringFromUtf8(const char* source) {
103 return String::NewFromUtf8(isolate(), source, NewStringType::kNormal)
104 .ToLocalChecked();
105 }
106
107 private:
108 Local<Context> serialization_context_;
109 Local<Context> deserialization_context_;
110
111 DISALLOW_COPY_AND_ASSIGN(ValueSerializerTest);
112 };
113
114 TEST_F(ValueSerializerTest, DecodeInvalid) {
115 // Version tag but no content.
116 InvalidDecodeTest({0xff});
117 // Version too large.
118 InvalidDecodeTest({0xff, 0x7f, 0x5f});
119 // Nonsense tag.
120 InvalidDecodeTest({0xff, 0x09, 0xdd});
121 }
122
123 TEST_F(ValueSerializerTest, RoundTripOddball) {
124 RoundTripTest([this]() { return Undefined(isolate()); },
125 [](Local<Value> value) { EXPECT_TRUE(value->IsUndefined()); });
126 RoundTripTest([this]() { return True(isolate()); },
127 [](Local<Value> value) { EXPECT_TRUE(value->IsTrue()); });
128 RoundTripTest([this]() { return False(isolate()); },
129 [](Local<Value> value) { EXPECT_TRUE(value->IsFalse()); });
130 RoundTripTest([this]() { return Null(isolate()); },
131 [](Local<Value> value) { EXPECT_TRUE(value->IsNull()); });
132 }
133
134 TEST_F(ValueSerializerTest, DecodeOddball) {
135 // What this code is expected to generate.
136 DecodeTest({0xff, 0x09, 0x5f},
137 [](Local<Value> value) { EXPECT_TRUE(value->IsUndefined()); });
138 DecodeTest({0xff, 0x09, 0x54},
139 [](Local<Value> value) { EXPECT_TRUE(value->IsTrue()); });
140 DecodeTest({0xff, 0x09, 0x46},
141 [](Local<Value> value) { EXPECT_TRUE(value->IsFalse()); });
142 DecodeTest({0xff, 0x09, 0x30},
143 [](Local<Value> value) { EXPECT_TRUE(value->IsNull()); });
144
145 // What v9 of the Blink code generates.
146 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x5f, 0x00},
147 [](Local<Value> value) { EXPECT_TRUE(value->IsUndefined()); });
148 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x54, 0x00},
149 [](Local<Value> value) { EXPECT_TRUE(value->IsTrue()); });
150 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x46, 0x00},
151 [](Local<Value> value) { EXPECT_TRUE(value->IsFalse()); });
152 DecodeTest({0xff, 0x09, 0x3f, 0x00, 0x30, 0x00},
153 [](Local<Value> value) { EXPECT_TRUE(value->IsNull()); });
154
155 // v0 (with no explicit version).
156 DecodeTest({0x5f, 0x00},
157 [](Local<Value> value) { EXPECT_TRUE(value->IsUndefined()); });
158 DecodeTest({0x54, 0x00},
159 [](Local<Value> value) { EXPECT_TRUE(value->IsTrue()); });
160 DecodeTest({0x46, 0x00},
161 [](Local<Value> value) { EXPECT_TRUE(value->IsFalse()); });
162 DecodeTest({0x30, 0x00},
163 [](Local<Value> value) { EXPECT_TRUE(value->IsNull()); });
164 }
165
166 } // namespace
167 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/unittests.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698