diff options
Diffstat (limited to 'gin')
-rw-r--r-- | gin/arguments.cc | 36 | ||||
-rw-r--r-- | gin/arguments.h | 54 | ||||
-rw-r--r-- | gin/array_buffer.cc | 93 | ||||
-rw-r--r-- | gin/array_buffer.h | 45 | ||||
-rw-r--r-- | gin/converter.cc | 36 | ||||
-rw-r--r-- | gin/converter.h | 24 | ||||
-rw-r--r-- | gin/dictionary.cc | 40 | ||||
-rw-r--r-- | gin/dictionary.h | 50 | ||||
-rw-r--r-- | gin/gin.gyp | 29 | ||||
-rw-r--r-- | gin/per_isolate_data.cc | 14 | ||||
-rw-r--r-- | gin/per_isolate_data.h | 6 | ||||
-rw-r--r-- | gin/runner.cc | 2 | ||||
-rw-r--r-- | gin/test/gtest.cc | 76 | ||||
-rw-r--r-- | gin/test/gtest.h | 16 |
14 files changed, 473 insertions, 48 deletions
diff --git a/gin/arguments.cc b/gin/arguments.cc new file mode 100644 index 0000000..15802b8 --- /dev/null +++ b/gin/arguments.cc @@ -0,0 +1,36 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gin/arguments.h" + +#include <sstream> +#include "gin/converter.h" + +namespace gin { + +Arguments::Arguments(const v8::FunctionCallbackInfo<v8::Value>& info) + : isolate_(info.GetIsolate()), + info_(info), + next_(0), + insufficient_arguments_(false) { +} + +Arguments::~Arguments() { +} + +void Arguments::ThrowError() { + if (insufficient_arguments_) + return ThrowTypeError("Insufficient number of arguments."); + + std::stringstream stream; + stream << "Error processing argument " << next_ - 1 << "."; + ThrowTypeError(stream.str()); +} + +void Arguments::ThrowTypeError(const std::string& message) { + isolate_->ThrowException(v8::Exception::TypeError( + StringToV8(isolate_, message))); +} + +} // namespace gin diff --git a/gin/arguments.h b/gin/arguments.h new file mode 100644 index 0000000..c5335cc --- /dev/null +++ b/gin/arguments.h @@ -0,0 +1,54 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GIN_ARGUMENTS_H_ +#define GIN_ARGUMENTS_H_ + +#include "base/basictypes.h" +#include "gin/converter.h" + +namespace gin { + +class Arguments { + public: + explicit Arguments(const v8::FunctionCallbackInfo<v8::Value>& info); + ~Arguments(); + + template<typename T> + bool Holder(T* out) { + return ConvertFromV8(info_.Holder(), out); + } + + template<typename T> + bool GetNext(T* out) { + if (next_ >= info_.Length()) { + insufficient_arguments_ = true; + return false; + } + v8::Handle<v8::Value> val = info_[next_++]; + return ConvertFromV8(val, out); + } + + template<typename T> + void Return(T val) { + info_.GetReturnValue().Set(ConvertToV8(isolate_, val)); + } + + void ThrowError(); + void ThrowTypeError(const std::string& message); + + v8::Isolate* isolate() const { return isolate_; } + + private: + v8::Isolate* isolate_; + const v8::FunctionCallbackInfo<v8::Value>& info_; + int next_; + bool insufficient_arguments_; + + DISALLOW_COPY_AND_ASSIGN(Arguments); +}; + +} // namespace gin + +#endif // GIN_ARGUMENTS_H_ diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc index e8236fc..43dd8da 100644 --- a/gin/array_buffer.cc +++ b/gin/array_buffer.cc @@ -32,7 +32,7 @@ ArrayBufferAllocator* ArrayBufferAllocator::SharedInstance() { return instance; } -// BufferView::Private -------------------------------------------------------- +// ArrayBuffer::Private ------------------------------------------------------- // This class exists to solve a tricky lifetime problem. The V8 API doesn't // want to expose a direct view into the memory behind an array buffer because @@ -42,18 +42,18 @@ ArrayBufferAllocator* ArrayBufferAllocator::SharedInstance() { // we're done with it and when V8 is done with it. // // To determine whether we're done with the memory, every view we have into -// the array buffer takes a reference to the BufferView::Private object that +// the array buffer takes a reference to the ArrayBuffer::Private object that // actually owns the memory. To determine when V8 is done with the memory, we // open a weak handle to the ArrayBuffer object. When we receive the weak // callback, we know the object is about to be garbage collected and we can // drop V8's implied reference to the memory. // -// The final subtlety is that we need every BufferView into the same array -// buffer to AddRef the same BufferView::Private. To make that work, we store a -// pointer to the BufferView::Private object in an internal field of the +// The final subtlety is that we need every ArrayBuffer into the same array +// buffer to AddRef the same ArrayBuffer::Private. To make that work, we store +// a pointer to the ArrayBuffer::Private object in an internal field of the // ArrayBuffer object. // -class BufferView::Private { +class ArrayBuffer::Private { public: static scoped_refptr<Private> From(v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> array); @@ -77,7 +77,7 @@ class BufferView::Private { size_t length_; }; -scoped_refptr<BufferView::Private> BufferView::Private::From( +scoped_refptr<ArrayBuffer::Private> ArrayBuffer::Private::From( v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> array) { if (array->IsExternal()) { return make_scoped_refptr(static_cast<Private*>( @@ -86,18 +86,18 @@ scoped_refptr<BufferView::Private> BufferView::Private::From( return make_scoped_refptr(new Private(isolate, array)); } -void BufferView::Private::AddRef() { +void ArrayBuffer::Private::AddRef() { ++ref_count_; } -void BufferView::Private::Release() { +void ArrayBuffer::Private::Release() { if (--ref_count_) return; delete this; } -BufferView::Private::Private(v8::Isolate* isolate, - v8::Handle<v8::ArrayBuffer> array) +ArrayBuffer::Private::Private(v8::Isolate* isolate, + v8::Handle<v8::ArrayBuffer> array) : ref_count_(0), array_buffer_(isolate, array) { // Take ownership of the array buffer. @@ -111,40 +111,73 @@ BufferView::Private::Private(v8::Isolate* isolate, array_buffer_.SetWeak(this, WeakCallback); } -BufferView::Private::~Private() { +ArrayBuffer::Private::~Private() { ArrayBufferAllocator::SharedInstance()->Free(buffer_, length_); } -void BufferView::Private::WeakCallback( +void ArrayBuffer::Private::WeakCallback( const v8::WeakCallbackData<v8::ArrayBuffer, Private>& data) { Private* parameter = data.GetParameter(); parameter->array_buffer_.Reset(); - parameter->Release(); // Balanced in BufferView::Private::Private. + parameter->Release(); // Balanced in ArrayBuffer::Private::Private. } -// BufferView ----------------------------------------------------------------- +// ArrayBuffer ---------------------------------------------------------------- -BufferView::BufferView(v8::Isolate* isolate, - v8::Handle<v8::ArrayBufferView> view) { - Initialize(isolate, view->Buffer()); - uint8_t* ptr = static_cast<uint8_t*>(bytes_); - bytes_ = static_cast<void*>(ptr + view->ByteOffset()); - num_bytes_ = view->ByteLength(); +ArrayBuffer::ArrayBuffer(v8::Isolate* isolate) + : isolate_(isolate), + bytes_(0), + num_bytes_(0) { } -BufferView::BufferView(v8::Isolate* isolate, - v8::Handle<v8::ArrayBuffer> array) { - Initialize(isolate, array); +ArrayBuffer::ArrayBuffer(v8::Isolate* isolate, + v8::Handle<v8::ArrayBuffer> array) + : isolate_(isolate) { + private_ = ArrayBuffer::Private::From(isolate_, array); + bytes_ = private_->buffer(); + num_bytes_ = private_->length(); } -BufferView::~BufferView() { +ArrayBuffer::~ArrayBuffer() { } -void BufferView::Initialize(v8::Isolate* isolate, - v8::Handle<v8::ArrayBuffer> array) { - private_ = BufferView::Private::From(isolate, array); - bytes_ = private_->buffer(); - num_bytes_ = private_->length(); +// Converter<ArrayBuffer> ----------------------------------------------------- + +bool Converter<ArrayBuffer>::FromV8(v8::Handle<v8::Value> val, + ArrayBuffer* out) { + if (!val->IsArrayBuffer()) + return false; + *out = ArrayBuffer(out->isolate(), v8::Handle<v8::ArrayBuffer>::Cast(val)); + return true; +} + +// ArrayBufferView ------------------------------------------------------------ + +ArrayBufferView::ArrayBufferView(v8::Isolate* isolate) + : array_buffer_(isolate), + offset_(0), + num_bytes_(0) { +} + +ArrayBufferView::ArrayBufferView(v8::Isolate* isolate, + v8::Handle<v8::ArrayBufferView> view) + : array_buffer_(isolate, view->Buffer()), + offset_(view->ByteOffset()), + num_bytes_(view->ByteLength()) { +} + +ArrayBufferView::~ArrayBufferView() { +} + +// Converter<ArrayBufferView> ------------------------------------------------- + +bool Converter<ArrayBufferView>::FromV8(v8::Handle<v8::Value> val, + ArrayBufferView* out) { + if (!val->IsArrayBufferView()) + return false; + *out = ArrayBufferView(out->isolate(), + v8::Handle<v8::ArrayBufferView>::Cast(val)); + return true; } } // namespace gin diff --git a/gin/array_buffer.h b/gin/array_buffer.h index b48a687..a645431 100644 --- a/gin/array_buffer.h +++ b/gin/array_buffer.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" // For scoped_refptr only! +#include "gin/converter.h" #include "v8/include/v8.h" namespace gin { @@ -21,25 +22,57 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { static ArrayBufferAllocator* SharedInstance(); }; -class BufferView { +class ArrayBuffer { public: - BufferView(v8::Isolate* isolate, v8::Handle<v8::ArrayBufferView> view); - BufferView(v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> buffer); - ~BufferView(); + explicit ArrayBuffer(v8::Isolate* isolate); + ArrayBuffer(v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> buffer); + ~ArrayBuffer(); void* bytes() const { return bytes_; } size_t num_bytes() const { return num_bytes_; } + v8::Isolate* isolate() const { return isolate_; } + private: class Private; - void Initialize(v8::Isolate* isolate, v8::Handle<v8::ArrayBuffer> buffer); - + v8::Isolate* isolate_; scoped_refptr<Private> private_; void* bytes_; size_t num_bytes_; }; +template<> +struct Converter<ArrayBuffer> { + static bool FromV8(v8::Handle<v8::Value> val, + ArrayBuffer* out); +}; + +class ArrayBufferView { + public: + explicit ArrayBufferView(v8::Isolate* isolate); + ArrayBufferView(v8::Isolate* isolate, v8::Handle<v8::ArrayBufferView> view); + ~ArrayBufferView(); + + void* bytes() const { + return static_cast<uint8_t*>(array_buffer_.bytes()) + offset_; + } + size_t num_bytes() const { return num_bytes_; } + + v8::Isolate* isolate() const { return array_buffer_.isolate(); } + + private: + ArrayBuffer array_buffer_; + size_t offset_; + size_t num_bytes_; +}; + +template<> +struct Converter<ArrayBufferView> { + static bool FromV8(v8::Handle<v8::Value> val, + ArrayBufferView* out); +}; + } // namespace gin #endif // GIN_ARRAY_BUFFER_H_ diff --git a/gin/converter.cc b/gin/converter.cc index 6b30985..8f9d0ab 100644 --- a/gin/converter.cc +++ b/gin/converter.cc @@ -49,6 +49,30 @@ bool Converter<uint32_t>::FromV8(Handle<Value> val, uint32_t* out) { return true; } +Handle<Value> Converter<int64_t>::ToV8(Isolate* isolate, int64_t val) { + return Number::New(isolate, static_cast<double>(val)).As<Value>(); +} + +bool Converter<int64_t>::FromV8(Handle<Value> val, int64_t* out) { + if (!val->IsNumber()) + return false; + // Even though IntegerValue returns int64_t, JavaScript cannot represent + // the full precision of int64_t, which means some rounding might occur. + *out = val->IntegerValue(); + return true; +} + +Handle<Value> Converter<uint64_t>::ToV8(Isolate* isolate, uint64_t val) { + return Number::New(isolate, static_cast<double>(val)).As<Value>(); +} + +bool Converter<uint64_t>::FromV8(Handle<Value> val, uint64_t* out) { + if (!val->IsNumber()) + return false; + *out = static_cast<uint64_t>(val->IntegerValue()); + return true; +} + Handle<Value> Converter<double>::ToV8(Isolate* isolate, double val) { return Number::New(isolate, val).As<Value>(); } @@ -87,7 +111,8 @@ bool Converter<Handle<Function> >::FromV8(Handle<Value> val, return true; } -Handle<Value> Converter<Handle<Object> >::ToV8(Handle<Object> val) { +Handle<Value> Converter<Handle<Object> >::ToV8(v8::Isolate* isolate, + Handle<Object> val) { return val.As<Value>(); } @@ -99,4 +124,13 @@ bool Converter<Handle<Object> >::FromV8(Handle<Value> val, return true; } +v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate, + const std::string& val) { + return String::NewFromUtf8(isolate, + val.data(), + String::kInternalizedString, + val.length()); +} + + } // namespace gin diff --git a/gin/converter.h b/gin/converter.h index eb84be2..551849b 100644 --- a/gin/converter.h +++ b/gin/converter.h @@ -40,6 +40,24 @@ struct Converter<uint32_t> { }; template<> +struct Converter<int64_t> { + // Warning: JavaScript cannot represent 64 integers precisely. + static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, + int64_t val); + static bool FromV8(v8::Handle<v8::Value> val, + int64_t* out); +}; + +template<> +struct Converter<uint64_t> { + // Warning: JavaScript cannot represent 64 integers precisely. + static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, + uint64_t val); + static bool FromV8(v8::Handle<v8::Value> val, + uint64_t* out); +}; + +template<> struct Converter<double> { static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, double val); @@ -63,7 +81,8 @@ struct Converter<v8::Handle<v8::Function> > { template<> struct Converter<v8::Handle<v8::Object> > { - static v8::Handle<v8::Value> ToV8(v8::Handle<v8::Object> val); + static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, + v8::Handle<v8::Object> val); static bool FromV8(v8::Handle<v8::Value> val, v8::Handle<v8::Object>* out); }; @@ -111,6 +130,9 @@ inline v8::Handle<v8::String> StringToV8( return ConvertToV8(isolate, input).As<v8::String>(); } +v8::Handle<v8::String> StringToSymbol(v8::Isolate* isolate, + const std::string& val); + template<typename T> bool ConvertFromV8(v8::Handle<v8::Value> input, T* result) { return Converter<T>::FromV8(input, result); diff --git a/gin/dictionary.cc b/gin/dictionary.cc new file mode 100644 index 0000000..0da85af --- /dev/null +++ b/gin/dictionary.cc @@ -0,0 +1,40 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gin/dictionary.h" + +namespace gin { + +Dictionary::Dictionary(v8::Isolate* isolate) + : isolate_(isolate) { +} + +Dictionary::Dictionary(v8::Isolate* isolate, + v8::Handle<v8::Object> object) + : isolate_(isolate), + object_(object) { +} + +Dictionary::~Dictionary() { +} + +Dictionary Dictionary::CreateEmpty(v8::Isolate* isolate) { + Dictionary dictionary(isolate); + dictionary.object_ = v8::Object::New(); + return dictionary; +} + +v8::Handle<v8::Value> Converter<Dictionary>::ToV8(v8::Isolate* isolate, + Dictionary val) { + return val.object_; +} + +bool FromV8(v8::Handle<v8::Value> val, Dictionary* out) { + if (!val->IsObject()) + return false; + *out = Dictionary(out->isolate(), v8::Handle<v8::Object>::Cast(val)); + return true; +} + +} // namespace gin diff --git a/gin/dictionary.h b/gin/dictionary.h new file mode 100644 index 0000000..f011779 --- /dev/null +++ b/gin/dictionary.h @@ -0,0 +1,50 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GIN_DICTIONARY_H_ +#define GIN_DICTIONARY_H_ + +#include "gin/converter.h" + +namespace gin { + +class Dictionary { + public: + explicit Dictionary(v8::Isolate* isolate); + Dictionary(v8::Isolate* isolate, v8::Handle<v8::Object> object); + ~Dictionary(); + + static Dictionary CreateEmpty(v8::Isolate* isolate); + + template<typename T> + bool Get(const std::string& key, T* out) { + v8::Handle<v8::Value> val = object_->Get(StringToV8(isolate_, key)); + return ConvertFromV8(val, out); + } + + template<typename T> + bool Set(const std::string& key, T val) { + return object_->Set(StringToV8(isolate_, key), ConvertToV8(isolate_, val)); + } + + v8::Isolate* isolate() const { return isolate_; } + + private: + friend struct Converter<Dictionary>; + + v8::Isolate* isolate_; + v8::Handle<v8::Object> object_; +}; + +template<> +struct Converter<Dictionary> { + static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, + Dictionary val); + static bool FromV8(v8::Handle<v8::Value> val, + Dictionary* out); +}; + +} // namespace gin + +#endif // GIN_DICTIONARY_H_ diff --git a/gin/gin.gyp b/gin/gin.gyp index ca133dd..ed76f09 100644 --- a/gin/gin.gyp +++ b/gin/gin.gyp @@ -20,10 +20,14 @@ '../v8/tools/gyp/v8.gyp:v8', ], 'sources': [ + 'arguments.cc', + 'arguments.h', 'array_buffer.cc', 'array_buffer.h', 'converter.cc', 'converter.h', + 'dictionary.cc', + 'dictionary.h', 'initialize.cc', 'initialize.h', 'per_isolate_data.cc', @@ -35,18 +39,35 @@ ], }, { - 'target_name': 'gin_unittests', - 'type': 'executable', + 'target_name': 'gin_test', + 'type': 'static_library', 'dependencies': [ '../base/base.gyp:base', - '../base/base.gyp:run_all_unittests', + '../testing/gtest.gyp:gtest', + 'gin', + ], + 'export_dependent_settings': [ + '../base/base.gyp:base', '../testing/gtest.gyp:gtest', 'gin', ], 'sources': [ + 'test/gtest.cc', + 'test/gtest.h', 'test/v8_test.cc', - 'test/run_all_unittests.cc', + 'test/v8_test.h', + ], + }, + { + 'target_name': 'gin_unittests', + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:run_all_unittests', + 'gin_test', + ], + 'sources': [ 'converter_unittest.cc', + 'test/run_all_unittests.cc', 'runner_unittest.cc', ], }, diff --git a/gin/per_isolate_data.cc b/gin/per_isolate_data.cc index 1320904..56b2c53 100644 --- a/gin/per_isolate_data.cc +++ b/gin/per_isolate_data.cc @@ -25,9 +25,17 @@ PerIsolateData* PerIsolateData::From(Isolate* isolate) { return static_cast<PerIsolateData*>(isolate->GetData()); } -void PerIsolateData::RegisterObjectTemplate( - WrapperInfo* info, Local<ObjectTemplate> object_template) { - object_templates_[info] = Eternal<ObjectTemplate>(isolate_, object_template); +void PerIsolateData::SetObjectTemplate(WrapperInfo* info, + Local<ObjectTemplate> templ) { + object_templates_[info] = Eternal<ObjectTemplate>(isolate_, templ); +} + +v8::Local<v8::ObjectTemplate> PerIsolateData::GetObjectTemplate( + WrapperInfo* info) { + ObjectTemplateMap::iterator it = object_templates_.find(info); + if (it == object_templates_.end()) + return v8::Local<v8::ObjectTemplate>(); + return it->second.Get(isolate_); } } // namespace gin diff --git a/gin/per_isolate_data.h b/gin/per_isolate_data.h index 72467b8..c92e9f3 100644 --- a/gin/per_isolate_data.h +++ b/gin/per_isolate_data.h @@ -20,8 +20,10 @@ class PerIsolateData { static PerIsolateData* From(v8::Isolate* isolate); - void RegisterObjectTemplate(WrapperInfo* info, - v8::Local<v8::ObjectTemplate> object_template); + void SetObjectTemplate(WrapperInfo* info, + v8::Local<v8::ObjectTemplate> object_template); + + v8::Local<v8::ObjectTemplate> GetObjectTemplate(WrapperInfo* info); private: typedef std::map< diff --git a/gin/runner.cc b/gin/runner.cc index cf98399..ec701b7 100644 --- a/gin/runner.cc +++ b/gin/runner.cc @@ -44,7 +44,7 @@ void Runner::Run(Handle<Script> script) { } v8::Handle<v8::Function> Runner::GetMain() { - Handle<Value> property = global()->Get(StringToV8(isolate_, "main")); + Handle<Value> property = global()->Get(StringToSymbol(isolate_, "main")); if (property.IsEmpty()) return v8::Handle<v8::Function>(); Handle<Function> main; diff --git a/gin/test/gtest.cc b/gin/test/gtest.cc new file mode 100644 index 0000000..2d77563 --- /dev/null +++ b/gin/test/gtest.cc @@ -0,0 +1,76 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gin/test/gtest.h" + +#include "gin/arguments.h" +#include "gin/converter.h" +#include "gin/per_isolate_data.h" +#include "gin/wrapper_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gin { + +namespace { + +void ExpectTrue(const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + + bool value = false; + std::string description; + + if (!args.GetNext(&value) || + !args.GetNext(&description)) { + return args.ThrowError(); + } + + EXPECT_TRUE(value) << description; +} + +void ExpectFalse(const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + + bool value = false; + std::string description; + + if (!args.GetNext(&value) || + !args.GetNext(&description)) { + return args.ThrowError(); + } + + EXPECT_FALSE(value) << description; +} + +void ExpectEqual(const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + + std::string description; + if (!ConvertFromV8(info[2], &description)) + return args.ThrowTypeError("Expected description."); + + EXPECT_TRUE(info[0]->StrictEquals(info[1])) << description; +} + +WrapperInfo g_gtest_wrapper_info = {}; + +} + +v8::Local<v8::ObjectTemplate> GetGTestTemplate(v8::Isolate* isolate) { + PerIsolateData* data = PerIsolateData::From(isolate); + v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( + &g_gtest_wrapper_info); + if (templ.IsEmpty()) { + templ = v8::ObjectTemplate::New(); + templ->Set(StringToSymbol(isolate, "expectTrue"), + v8::FunctionTemplate::New(ExpectTrue)); + templ->Set(StringToSymbol(isolate, "expectFalse"), + v8::FunctionTemplate::New(ExpectFalse)); + templ->Set(StringToSymbol(isolate, "expectEqual"), + v8::FunctionTemplate::New(ExpectEqual)); + data->SetObjectTemplate(&g_gtest_wrapper_info, templ); + } + return templ; +} + +} // namespace gin diff --git a/gin/test/gtest.h b/gin/test/gtest.h new file mode 100644 index 0000000..e4ad534 --- /dev/null +++ b/gin/test/gtest.h @@ -0,0 +1,16 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GIN_TEST_GTEST_H_ +#define GIN_TEST_GTEST_H_ + +#include "v8/include/v8.h" + +namespace gin { + +v8::Local<v8::ObjectTemplate> GetGTestTemplate(v8::Isolate* isolate); + +} // namespace gin + +#endif // GIN_TEST_GTEST_H_ |