[Pkg-javascript-commits] [node-nan] 01/03: Imported Upstream version 1.3.0

Jérémy Lal kapouer at moszumanska.debian.org
Sat Sep 6 20:40:55 UTC 2014


This is an automated email from the git hooks/post-receive script.

kapouer pushed a commit to branch master
in repository node-nan.

commit 419972dafdfa57571faca6961690b5098350ebdd
Author: Jérémy Lal <kapouer at melix.org>
Date:   Sat Sep 6 22:35:55 2014 +0200

    Imported Upstream version 1.3.0
---
 .dntrc                                 |  25 +-
 .travis.yml                            |  18 +-
 CHANGELOG.md                           | 200 +++++++++++++
 README.md                              | 109 +++++--
 appveyor.yml                           |  32 +++
 examples/async_pi_estimate/pi_est.cc   |  25 +-
 nan.h                                  | 500 +++++++++++++++++++++------------
 package.json                           |  12 +-
 test/binding.gyp                       |  14 +
 test/cpp/isolatedata.cpp               |  38 +++
 test/cpp/makecallback.cpp              |  74 +++++
 test/cpp/multifile2.cpp                |   4 +-
 test/cpp/news.cpp                      |  13 +-
 test/cpp/settemplate.cpp               |   9 +-
 test/cpp/settergetter.cpp              |  91 ++++--
 test/cpp/strings.cpp                   | 178 ++++--------
 test/js/asyncworker-test.js            |   7 +-
 test/js/asyncworkererror-test.js       |   5 +-
 test/js/bufferworkerpersistent-test.js |  11 +-
 test/js/isolatedata-test.js            |  11 +
 test/js/makecallback-test.js           |  24 ++
 test/js/morenews-test.js               |  35 +--
 test/js/multifile-test.js              |   5 +-
 test/js/news-test.js                   |  95 ++++---
 test/js/optionvalues-test.js           |   7 +-
 test/js/persistent-test.js             |   5 +-
 test/js/returnemptystring-test.js      |   9 +-
 test/js/returnnull-test.js             |   9 +-
 test/js/returnundefined-test.js        |   9 +-
 test/js/returnvalue-test.js            |   9 +-
 test/js/settemplate-test.js            |  54 +++-
 test/js/settergetter-test.js           |   5 +-
 test/js/strings-test.js                |  81 ++----
 test/js/symbols-test.js                |   7 +-
 test/js/weak-test.js                   |   5 +-
 test/package.json                      |  16 --
 36 files changed, 1188 insertions(+), 563 deletions(-)

diff --git a/.dntrc b/.dntrc
index fc7ee64..47971da 100644
--- a/.dntrc
+++ b/.dntrc
@@ -4,13 +4,8 @@
 NODE_VERSIONS="\
   master   \
   v0.11.13 \
-  v0.11.10 \
-  v0.11.9  \
-  v0.11.8  \
-  v0.11.7  \
-  v0.11.6  \
-  v0.11.5  \
-  v0.11.4  \
+  v0.10.30 \
+  v0.10.29 \
   v0.10.28 \
   v0.10.26 \
   v0.10.25 \
@@ -20,18 +15,16 @@ NODE_VERSIONS="\
   v0.10.21 \
   v0.10.20 \
   v0.10.19 \
-  v0.10.18 \
+  v0.8.28  \
+  v0.8.27  \
   v0.8.26  \
-  v0.8.25  \
   v0.8.24  \
-  v0.8.23  \
-  v0.8.22  \
 "
 OUTPUT_PREFIX="nan-"
-TEST_CMD="\
-  cd /dnt/test/ &&                                               \
-  npm install &&                                                 \
-  node_modules/.bin/node-gyp --nodedir /usr/src/node/ rebuild && \
-  node_modules/.bin/tap --gc js/*-test.js;                            \
+TEST_CMD="                                                                        \
+  cd /dnt/ &&                                                                     \
+  npm install &&                                                                  \
+  node_modules/.bin/node-gyp --nodedir /usr/src/node/ rebuild --directory test && \
+  node_modules/.bin/tap --gc test/js/*-test.js                                    \
 "
 
diff --git a/.travis.yml b/.travis.yml
index 068d49b..ca76fc3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,11 +1,10 @@
 language: node_js
 env:
-  - NODE_VERSION="0.6"
   - NODE_VERSION="0.8"
-  - NODE_VERSION="0.10.25"
-  - NODE_VERSION="0.10.26"
   - NODE_VERSION="0.10.27"
   - NODE_VERSION="0.10.28"
+  - NODE_VERSION="0.10.29"
+  - NODE_VERSION="0.10.30"
   - NODE_VERSION="0.11.13"
 node_js:
   - "0.10"
@@ -13,12 +12,15 @@ notifications:
   email:
     - rod at vagg.org
 before_install:
+  - npm install npm
+  - mv node_modules npm
+  - npm/.bin/npm --version
+  - npm/.bin/npm install
   - rm -rf ~/.nvm
-  - curl https://raw.github.com/creationix/nvm/master/install.sh | sh
+  - git clone https://github.com/creationix/nvm.git ~/.nvm
   - source ~/.nvm/nvm.sh
   - nvm install $NODE_VERSION
   - node --version
-  - npm --version
-  - cd test
-  - npm install
-script: npm test
+  - node_modules/.bin/node-gyp rebuild --directory test
+install:
+script: tap --gc test/js/*-test.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..146cbb5
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,200 @@
+# NAN ChangeLog
+
+### Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30
+
+
+**1.3.0 Aug 2 2014**
+
+ - Added NanNew<v8::String, std::string>(std::string)
+ - Added NanNew<v8::String, std::string&>(std::string&)
+ - Added NanAsciiString helper class
+ - Added NanUtf8String helper class
+ - Added NanUcs2String helper class
+ - Deprecated NanRawString()
+ - Deprecated NanCString()
+ - Added NanGetIsolateData(v8::Isolate *isolate)
+ - Added NanMakeCallback(v8::Handle<v8::Object> target, v8::Handle<v8::Function> func, int argc, v8::Handle<v8::Value>* argv)
+ - Added NanMakeCallback(v8::Handle<v8::Object> target, v8::Handle<v8::String> symbol, int argc, v8::Handle<v8::Value>* argv)
+ - Added NanMakeCallback(v8::Handle<v8::Object> target, const char* method, int argc, v8::Handle<v8::Value>* argv)
+ - Added NanSetTemplate(v8::Handle<v8::Template> templ, v8::Handle<v8::String> name , v8::Handle<v8::Data> value, v8::PropertyAttribute attributes)
+ - Added NanSetPrototypeTemplate(v8::Local<v8::FunctionTemplate> templ, v8::Handle<v8::String> name, v8::Handle<v8::Data> value, v8::PropertyAttribute attributes)
+ - Added NanSetInstanceTemplate(v8::Local<v8::FunctionTemplate> templ, const char *name, v8::Handle<v8::Data> value)
+ - Added NanSetInstanceTemplate(v8::Local<v8::FunctionTemplate> templ, v8::Handle<v8::String> name, v8::Handle<v8::Data> value, v8::PropertyAttribute attributes)
+
+**1.2.0 Jun 5 2014**
+
+ - Add NanSetPrototypeTemplate
+ - Changed NAN_WEAK_CALLBACK internals, switched _NanWeakCallbackData to class,
+     introduced _NanWeakCallbackDispatcher
+ - Removed -Wno-unused-local-typedefs from test builds
+ - Made test builds Windows compatible ('Sleep()')
+
+**1.1.2 May 28 2014**
+
+ - Release to fix more stuff-ups in 1.1.1
+
+**1.1.1 May 28 2014**
+
+ - Release to fix version mismatch in nan.h and lack of changelog entry for 1.1.0
+
+**1.1.0 May 25 2014**
+
+ - Remove nan_isolate, use v8::Isolate::GetCurrent() internally instead
+ - Additional explicit overloads for NanNew(): (char*,int), (uint8_t*[,int]),
+     (uint16_t*[,int), double, int, unsigned int, bool, v8::String::ExternalStringResource*,
+     v8::String::ExternalAsciiStringResource*
+ - Deprecate NanSymbol()
+ - Added SetErrorMessage() and ErrorMessage() to NanAsyncWorker
+
+**1.0.0 May 4 2014**
+
+ - Heavy API changes for V8 3.25 / Node 0.11.13
+ - Use cpplint.py
+ - Removed NanInitPersistent
+ - Removed NanPersistentToLocal
+ - Removed NanFromV8String
+ - Removed NanMakeWeak
+ - Removed NanNewLocal
+ - Removed NAN_WEAK_CALLBACK_OBJECT
+ - Removed NAN_WEAK_CALLBACK_DATA
+ - Introduce NanNew, replaces NanNewLocal, NanPersistentToLocal, adds many overloaded typed versions
+ - Introduce NanUndefined, NanNull, NanTrue and NanFalse
+ - Introduce NanEscapableScope and NanEscapeScope
+ - Introduce NanMakeWeakPersistent (requires a special callback to work on both old and new node)
+ - Introduce NanMakeCallback for node::MakeCallback
+ - Introduce NanSetTemplate
+ - Introduce NanGetCurrentContext
+ - Introduce NanCompileScript and NanRunScript
+ - Introduce NanAdjustExternalMemory
+ - Introduce NanAddGCEpilogueCallback, NanAddGCPrologueCallback, NanRemoveGCEpilogueCallback, NanRemoveGCPrologueCallback
+ - Introduce NanGetHeapStatistics
+ - Rename NanAsyncWorker#SavePersistent() to SaveToPersistent()
+
+**0.8.0 Jan 9 2014**
+
+ - NanDispose -> NanDisposePersistent, deprecate NanDispose
+ - Extract _NAN_*_RETURN_TYPE, pull up NAN_*()
+
+**0.7.1 Jan 9 2014**
+
+ - Fixes to work against debug builds of Node
+ - Safer NanPersistentToLocal (avoid reinterpret_cast)
+ - Speed up common NanRawString case by only extracting flattened string when necessary
+
+**0.7.0 Dec 17 2013**
+
+ - New no-arg form of NanCallback() constructor.
+ - NanCallback#Call takes Handle rather than Local
+ - Removed deprecated NanCallback#Run method, use NanCallback#Call instead
+ - Split off _NAN_*_ARGS_TYPE from _NAN_*_ARGS
+ - Restore (unofficial) Node 0.6 compatibility at NanCallback#Call()
+ - Introduce NanRawString() for char* (or appropriate void*) from v8::String
+     (replacement for NanFromV8String)
+ - Introduce NanCString() for null-terminated char* from v8::String
+
+**0.6.0 Nov 21 2013**
+
+ - Introduce NanNewLocal<T>(v8::Handle<T> value) for use in place of
+     v8::Local<T>::New(...) since v8 started requiring isolate in Node 0.11.9
+
+**0.5.2 Nov 16 2013**
+
+ - Convert SavePersistent and GetFromPersistent in NanAsyncWorker from protected and public
+
+**0.5.1 Nov 12 2013**
+
+ - Use node::MakeCallback() instead of direct v8::Function::Call()
+
+**0.5.0 Nov 11 2013**
+
+ - Added @TooTallNate as collaborator
+ - New, much simpler, "include_dirs" for binding.gyp
+ - Added full range of NAN_INDEX_* macros to match NAN_PROPERTY_* macros
+
+**0.4.4 Nov 2 2013**
+
+ - Isolate argument from v8::Persistent::MakeWeak removed for 0.11.8+
+
+**0.4.3 Nov 2 2013**
+
+ - Include node_object_wrap.h, removed from node.h for Node 0.11.8.
+
+**0.4.2 Nov 2 2013**
+
+ - Handle deprecation of v8::Persistent::Dispose(v8::Isolate* isolate)) for
+     Node 0.11.8 release.
+
+**0.4.1 Sep 16 2013**
+
+ - Added explicit `#include <uv.h>` as it was removed from node.h for v0.11.8
+
+**0.4.0 Sep 2 2013**
+
+ - Added NAN_INLINE and NAN_DEPRECATED and made use of them
+ - Added NanError, NanTypeError and NanRangeError
+ - Cleaned up code
+
+**0.3.2 Aug 30 2013**
+
+ - Fix missing scope declaration in GetFromPersistent() and SaveToPersistent
+     in NanAsyncWorker
+
+**0.3.1 Aug 20 2013**
+
+ - fix "not all control paths return a value" compile warning on some platforms
+
+**0.3.0 Aug 19 2013**
+
+ - Made NAN work with NPM
+ - Lots of fixes to NanFromV8String, pulling in features from new Node core
+ - Changed node::encoding to Nan::Encoding in NanFromV8String to unify the API
+ - Added optional error number argument for NanThrowError()
+ - Added NanInitPersistent()
+ - Added NanReturnNull() and NanReturnEmptyString()
+ - Added NanLocker and NanUnlocker
+ - Added missing scopes
+ - Made sure to clear disposed Persistent handles
+ - Changed NanAsyncWorker to allocate error messages on the heap
+ - Changed NanThrowError(Local<Value>) to NanThrowError(Handle<Value>)
+ - Fixed leak in NanAsyncWorker when errmsg is used
+
+**0.2.2 Aug 5 2013**
+
+ - Fixed usage of undefined variable with node::BASE64 in NanFromV8String()
+
+**0.2.1 Aug 5 2013**
+
+ - Fixed 0.8 breakage, node::BUFFER encoding type not available in 0.8 for
+     NanFromV8String()
+
+**0.2.0 Aug 5 2013**
+
+ - Added NAN_PROPERTY_GETTER, NAN_PROPERTY_SETTER, NAN_PROPERTY_ENUMERATOR,
+     NAN_PROPERTY_DELETER, NAN_PROPERTY_QUERY
+ - Extracted _NAN_METHOD_ARGS, _NAN_GETTER_ARGS, _NAN_SETTER_ARGS,
+     _NAN_PROPERTY_GETTER_ARGS, _NAN_PROPERTY_SETTER_ARGS,
+     _NAN_PROPERTY_ENUMERATOR_ARGS, _NAN_PROPERTY_DELETER_ARGS,
+     _NAN_PROPERTY_QUERY_ARGS
+ - Added NanGetInternalFieldPointer, NanSetInternalFieldPointer
+ - Added NAN_WEAK_CALLBACK, NAN_WEAK_CALLBACK_OBJECT,
+     NAN_WEAK_CALLBACK_DATA, NanMakeWeak
+ - Renamed THROW_ERROR to _NAN_THROW_ERROR
+ - Added NanNewBufferHandle(char*, size_t, node::smalloc::FreeCallback, void*)
+ - Added NanBufferUse(char*, uint32_t)
+ - Added NanNewContextHandle(v8::ExtensionConfiguration*,
+       v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Value>)
+ - Fixed broken NanCallback#GetFunction()
+ - Added optional encoding and size arguments to NanFromV8String()
+ - Added NanGetPointerSafe() and NanSetPointerSafe()
+ - Added initial test suite (to be expanded)
+ - Allow NanUInt32OptionValue to convert any Number object
+
+**0.1.0 Jul 21 2013**
+
+ - Added `NAN_GETTER`, `NAN_SETTER`
+ - Added `NanThrowError` with single Local<Value> argument
+ - Added `NanNewBufferHandle` with single uint32_t argument
+ - Added `NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>)`
+ - Added `Local<Function> NanCallback#GetFunction()`
+ - Added `NanCallback#Call(int, Local<Value>[])`
+ - Deprecated `NanCallback#Run(int, Local<Value>[])` in favour of Call
diff --git a/README.md b/README.md
index 69e7f78..2904a38 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,15 @@ Native Abstractions for Node.js
 
 **A header file filled with macro and utility goodness for making add-on development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.**
 
-***Current version: 1.2.0*** *(See [nan.h](https://github.com/rvagg/nan/blob/master/nan.h) for complete ChangeLog)*
+***Current version: 1.3.0***
+
+*(See [nan.h](https://github.com/rvagg/nan/blob/master/CHANGELOG.md) for complete ChangeLog)*
 
 [![NPM](https://nodei.co/npm/nan.png?downloads=true)](https://nodei.co/npm/nan/) [![NPM](https://nodei.co/npm-dl/nan.png?months=6)](https://nodei.co/npm/nan/)
 
+[![Build Status](https://secure.travis-ci.org/rvagg/nan.png)](http://travis-ci.org/rvagg/nan)
+[![Build status](https://ci.appveyor.com/api/projects/status/kh73pbm9dsju7fgh)](https://ci.appveyor.com/project/RodVagg/nan)
+
 Thanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.11/0.12, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect `NODE_MODULE_VERSION` and get yourself into a macro-tangle.
 
 This project also contains some helper utilities that make addon development a bit more pleasant.
@@ -19,6 +24,13 @@ This project also contains some helper utilities that make addon development a b
 <a name="news"></a>
 ## News & Updates
 
+### Aug-2014: 1.3.0 release
+
+* `NanCString()` and `NanRawString()` have been deprecated in favour of new <a href="#api_nan_ascii_string"><b><code>NanAsciiString</code></b></a>, <a href="#api_nan_utf8_string"><b><code>NanUtf8String</code></b></a> and <a href="#api_nan_ucs2_string"><b><code>NanUcs2String</code></b></a>. These classes manage the underlying memory for you in a safer way than just handing off an allocated array. You should now `*NanAsciiString(handle)` to access the raw `char` data, you can also allocate [...]
+* Two more <a href="#api_nan_make_callback"><b><code>NanMakeCallback</code></b></a> overloads have been added to for parity with Node core.
+* You can now `NanNew(std::string)` (use `NanNew<std::string&>(std::string&)` to pass by reference)
+* <a href="#api_nan_set_template"><b><code>NanSetTemplate</code></b></a>, <a href="#api_nan_set_prototype_template"><b><code>NanSetPrototypeTemplate</code></b></a> and <a href="#api_nan_set_instance_template"><b><code>NanSetInstanceTemplate</code></b></a> have been added.
+
 ### May-2014: 1.1.0 release
 
 * We've deprecated `NanSymbol()`, you should just use `NanNew<String>()` now.
@@ -144,6 +156,14 @@ NAN_METHOD(CalculateSync) {
 ```
 
 ```c++
+// async.h
+#include <node.h>
+#include <nan.h>
+
+NAN_METHOD(CalculateAsync);
+```
+
+```c++
 // async.cc
 #include <node.h>
 #include <nan.h>
@@ -241,8 +261,11 @@ NAN_METHOD(CalculateAsync) {
  * <del><a href="#api_nan_symbol"><b><code>NanSymbol</code></b></a></del>
  * <a href="#api_nan_get_pointer_safe"><b><code>NanGetPointerSafe</code></b></a>
  * <a href="#api_nan_set_pointer_safe"><b><code>NanSetPointerSafe</code></b></a>
- * <a href="#api_nan_raw_string"><b><code>NanRawString</code></b></a>
- * <a href="#api_nan_c_string"><b><code>NanCString</code></b></a>
+ * <del><a href="#api_nan_raw_string"><b><code>NanRawString</code></b></a></del>
+ * <del><a href="#api_nan_c_string"><b><code>NanCString</code></b></a></del>
+ * <a href="#api_nan_ascii_string"><b><code>NanAsciiString</code></b></a>
+ * <a href="#api_nan_utf8_string"><b><code>NanUtf8String</code></b></a>
+ * <a href="#api_nan_ucs2_string"><b><code>NanUcs2String</code></b></a>
  * <a href="#api_nan_boolean_option_value"><b><code>NanBooleanOptionValue</code></b></a>
  * <a href="#api_nan_uint32_option_value"><b><code>NanUInt32OptionValue</code></b></a>
  * <a href="#api_nan_error"><b><code>NanError</code></b>, <b><code>NanTypeError</code></b>, <b><code>NanRangeError</code></b></a>
@@ -257,6 +280,7 @@ NAN_METHOD(CalculateAsync) {
  * <a href="#api_nan_make_weak_persistent"><b><code>NanMakeWeakPersistent</code></b></a>
  * <a href="#api_nan_set_template"><b><code>NanSetTemplate</code></b></a>
  * <a href="#api_nan_set_prototype_template"><b><code>NanSetPrototypeTemplate</code></b></a>
+ * <a href="#api_nan_set_instance_template"><b><code>NanSetInstanceTemplate</code></b></a>
  * <a href="#api_nan_make_callback"><b><code>NanMakeCallback</code></b></a>
  * <a href="#api_nan_compile_script"><b><code>NanCompileScript</code></b></a>
  * <a href="#api_nan_run_script"><b><code>NanRunScript</code></b></a>
@@ -417,6 +441,12 @@ NAN_INLINE int foo(int bar) {
 
 Use `NanNew` to construct almost all v8 objects and make new local handles.
 
+Note: Using NanNew with an std::string is possible, however, you should ensure
+to use the overload version (`NanNew(stdString)`) rather than the template
+version (`NanNew<v8::String>(stdString)`) as there is an unnecessary
+performance penalty to using the template version because of the inability for
+compilers to appropriately deduce to reference types on template specialization. 
+
 ```c++
 Local<String> s = NanNew<String>("value");
 
@@ -522,7 +552,7 @@ This method is not directly exposed to V8, nor does it return a handle, so it us
 ```c++
 bool Foo::Bar() {
   NanScope();
-  
+
   Local<Boolean> val = NanFalse();
   ...
   return val->Value();
@@ -648,23 +678,27 @@ const char *plugh(size_t *outputsize) {
 ```
 
 <a name="api_nan_raw_string"></a>
-### void* NanRawString(Handle<Value>, enum Nan::Encoding, size_t *, void *, size_t, int)
+### <del>void* NanRawString(Handle<Value>, enum Nan::Encoding, size_t *, void *, size_t, int)</del>
+
+Deprecated. Use something else.
 
-When you want to convert a V8 `String` to a `char*` buffer, use `NanRawString`. You have to supply an encoding as well as a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows setting `String::WriteOptions`.
-Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer:
+<del>When you want to convert a V8 `String` to a `char*` buffer, use `NanRawString`. You have to supply an encoding as well as a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows setting `String::WriteOptions`.
+Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer:</del>
 
 ```c++
 size_t count;
 void* decoded = NanRawString(args[1], Nan::BASE64, &count, NULL, 0, String::HINT_MANY_WRITES_EXPECTED);
 ...
-delete[] decoded;
+delete[] reinterpret_cast<char*>(decoded);
 ```
 
 <a name="api_nan_c_string"></a>
-### char* NanCString(Handle<Value>, size_t *[, char *, size_t, int])
+### <del>char* NanCString(Handle<Value>, size_t *[, char *, size_t, int])</del>
 
-When you want to convert a V8 `String` to a null-terminated C `char*` use `NanCString`. The resulting `char*` will be UTF-8-encoded, and you need to supply a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows optionally setting `String::WriteOptions`, which default to `v8::String::NO_OPTIONS`.
-Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer:
+Deprecated. Use `NanUtf8String` instead.
+
+<del>When you want to convert a V8 `String` to a null-terminated C `char*` use `NanCString`. The resulting `char*` will be UTF-8-encoded, and you need to supply a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows optionally setting `String::WriteOptions`, which default to `v8::String::NO_OPTIONS`.
+Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer:</del>
 
 ```c++
 size_t count;
@@ -673,6 +707,42 @@ char* name = NanCString(args[0], &count);
 delete[] name;
 ```
 
+<a name="api_nan_ascii_string"></a>
+### NanAsciiString
+
+Convert a `String` to zero-terminated, Ascii-encoded `char *`.
+
+```c++
+NAN_METHOD(foo) {
+  NanScope();
+  NanReturnValue(NanNew(*NanAsciiString(arg[0])));
+}
+```
+
+<a name="api_nan_utf8_string"></a>
+### NanUtf8String
+
+Convert a `String` to zero-terminated, Utf8-encoded `char *`.
+
+```c++
+NAN_METHOD(foo) {
+  NanScope();
+  NanReturnValue(NanNew(*NanUtf8String(arg[0])));
+}
+```
+
+<a name="api_nan_ucs2_string"></a>
+### NanUcs2String
+
+Convert a `String` to zero-terminated, Ucs2-encoded `uint16_t *`.
+
+```c++
+NAN_METHOD(foo) {
+  NanScope();
+  NanReturnValue(NanNew(*NanUcs2String(arg[0])));
+}
+```
+
 <a name="api_nan_boolean_option_value"></a>
 ### bool NanBooleanOptionValue(Handle<Value>, Handle<String>[, bool])
 
@@ -814,15 +884,20 @@ NanMakeWeakPersistent(func, parameter, &weakCallback);
 ```
 
 <a name="api_nan_set_template"></a>
-### NanSetTemplate(templ, name, value)
+### NanSetTemplate(templ, name, value [, attributes])
 
 Use to add properties on object and function templates.
 
 <a name="api_nan_set_prototype_template"></a>
-### NanSetPrototypeTemplate(templ, name, value)
+### NanSetPrototypeTemplate(templ, name, value [, attributes])
 
 Use to add prototype properties on function templates.
 
+<a name="api_nan_set_instance_template"></a>
+### NanSetInstanceTemplate(templ, name, value [, attributes])
+
+Use to add instance properties on function templates.
+
 <a name="api_nan_make_callback"></a>
 ### NanMakeCallback(target, func, argc, argv)
 
@@ -841,7 +916,7 @@ Use to run both bound and unbound scripts.
 <a name="api_nan_adjust_external_memory"></a>
 ### NanAdjustExternalMemory(int change_in_bytes)
 
-Simply does `AdjustAmountOfExternalAllocatedMemory`
+Simply does `AdjustAmountOfExternalAllocatedMemory`, note that the argument and returned value have type `int`.
 
 <a name="api_nan_add_gc_epilogue_callback"></a>
 ### NanAddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type_filter=kGCTypeAll)
@@ -935,13 +1010,13 @@ public:
 
   // Fetch a stored V8 object (don't call from within `Execute()`)
   Local<Object> GetFromPersistent(const char *key);
-  
+
   // Get the error message (or NULL)
   const char *ErrorMessage();
-  
+
   // Set an error message
   void SetErrorMessage(const char *msg);
-  
+
 protected:
   // Default implementation calls the callback function with no arguments.
   // Override this to return meaningful data
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..657eed6
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,32 @@
+# http://www.appveyor.com/docs/appveyor-yml
+
+# Test against these versions of Node.js.
+environment:
+  matrix:
+    - nodejs_version: "0.8"
+    - nodejs_version: "0.10"
+    - nodejs_version: "0.11"
+
+# Install scripts. (runs after repo cloning)
+install:
+  # Get the latest stable version of Node 0.STABLE.latest
+  - npm install npm
+  - move node_modules npm
+  - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)
+  # Typical npm stuff.
+  - npm/.bin/npm install
+  - npm/.bin/npm run rebuild-tests
+
+# Post-install test scripts.
+test_script:
+  # Output useful info for debugging.
+  - node --version
+  - npm --version
+  - cmd: npm test
+
+# Don't actually build.
+build: off
+
+# Set build version format here instead of in the admin panel.
+version: "{build}"
+
diff --git a/examples/async_pi_estimate/pi_est.cc b/examples/async_pi_estimate/pi_est.cc
index 5e8fbd1..59d0f5e 100644
--- a/examples/async_pi_estimate/pi_est.cc
+++ b/examples/async_pi_estimate/pi_est.cc
@@ -22,17 +22,34 @@ See https://en.wikipedia.org/wiki/File:Pi_30K.gif
 for a visualization of how this works.
 */
 
+inline int randall(unsigned int *p_seed) {
+// windows has thread safe rand()
+#ifdef _WIN32
+  return rand();  // NOLINT(runtime/threadsafe_fn)
+#else
+  return rand_r(p_seed);
+#endif
+}
+
 double Estimate (int points) {
   int i = points;
   int inside = 0;
   unsigned int randseed = 1;
+
+#ifdef _WIN32
+  srand(randseed);
+#endif
+
   // unique seed for each run, for threaded use
-  unsigned int seed = rand_r(&randseed);
+  unsigned int seed = randall(&randseed);
+  
+#ifdef _WIN32
+  srand(seed);
+#endif
 
   while (i-- > 0) {
-    // rand_r() is used to avoid thread locking
-    double x = rand_r(&seed) / static_cast<double>(RAND_MAX);
-    double y = rand_r(&seed) / static_cast<double>(RAND_MAX);
+    double x = randall(&seed) / static_cast<double>(RAND_MAX);
+    double y = randall(&seed) / static_cast<double>(RAND_MAX);
 
     // x & y and now values between 0 and 1
     // now do a pythagorean diagonal calculation
diff --git a/nan.h b/nan.h
index 39b99b9..063de4e 100644
--- a/nan.h
+++ b/nan.h
@@ -11,162 +11,7 @@
  *
  * MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/LICENSE>
  *
- * Version 1.2.0 (current Node unstable: 0.11.13, Node stable: 0.10.28)
- *
- * ChangeLog:
- *  * 1.2.0 Jun 5 2015
- *    - Add NanSetPrototypeTemplate
- *    - Changed NAN_WEAK_CALLBACK internals, switched _NanWeakCallbackData to class,
- *      introduced _NanWeakCallbackDispatcher
- *    - Removed -Wno-unused-local-typedefs from test builds
- *    - Made test builds Windows compatible ('Sleep()')
- * `
- *  * 1.1.2 May 28 2014
- *    - Release to fix more stuff-ups in 1.1.1
- *
- *  * 1.1.1 May 28 2014
- *    - Release to fix version mismatch in nan.h and lack of changelog entry for 1.1.0
- *
- *  * 1.1.0 May 25 2014
- *    - Remove nan_isolate, use v8::Isolate::GetCurrent() internally instead
- *    - Additional explicit overloads for NanNew(): (char*,int), (uint8_t*[,int]),
- *      (uint16_t*[,int), double, int, unsigned int, bool, v8::String::ExternalStringResource*,
- *      v8::String::ExternalAsciiStringResource*
- *    - Deprecate NanSymbol()
- *    - Added SetErrorMessage() and ErrorMessage() to NanAsyncWorker
- *
- *  * 1.0.0 May 4 2014
- *    - Heavy API changes for V8 3.25 / Node 0.11.13
- *    - Use cpplint.py
- *    - Removed NanInitPersistent
- *    - Removed NanPersistentToLocal
- *    - Removed NanFromV8String
- *    - Removed NanMakeWeak
- *    - Removed NanNewLocal
- *    - Removed NAN_WEAK_CALLBACK_OBJECT
- *    - Removed NAN_WEAK_CALLBACK_DATA
- *    - Introduce NanNew, replaces NanNewLocal, NanPersistentToLocal, adds many overloaded typed versions
- *    - Introduce NanUndefined, NanNull, NanTrue and NanFalse
- *    - Introduce NanEscapableScope and NanEscapeScope
- *    - Introduce NanMakeWeakPersistent (requires a special callback to work on both old and new node)
- *    - Introduce NanMakeCallback for node::MakeCallback
- *    - Introduce NanSetTemplate
- *    - Introduce NanGetCurrentContext
- *    - Introduce NanCompileScript and NanRunScript
- *    - Introduce NanAdjustExternalMemory
- *    - Introduce NanAddGCEpilogueCallback, NanAddGCPrologueCallback, NanRemoveGCEpilogueCallback, NanRemoveGCPrologueCallback
- *    - Introduce NanGetHeapStatistics
- *    - Rename NanAsyncWorker#SavePersistent() to SaveToPersistent()
- *
- *  * 0.8.0 Jan 9 2014
- *    - NanDispose -> NanDisposePersistent, deprecate NanDispose
- *    - Extract _NAN_*_RETURN_TYPE, pull up NAN_*()
- *
- *  * 0.7.1 Jan 9 2014
- *    - Fixes to work against debug builds of Node
- *    - Safer NanPersistentToLocal (avoid reinterpret_cast)
- *    - Speed up common NanRawString case by only extracting flattened string when necessary
- *
- *  * 0.7.0 Dec 17 2013
- *    - New no-arg form of NanCallback() constructor.
- *    - NanCallback#Call takes Handle rather than Local
- *    - Removed deprecated NanCallback#Run method, use NanCallback#Call instead
- *    - Split off _NAN_*_ARGS_TYPE from _NAN_*_ARGS
- *    - Restore (unofficial) Node 0.6 compatibility at NanCallback#Call()
- *    - Introduce NanRawString() for char* (or appropriate void*) from v8::String
- *      (replacement for NanFromV8String)
- *    - Introduce NanCString() for null-terminated char* from v8::String
- *
- *  * 0.6.0 Nov 21 2013
- *    - Introduce NanNewLocal<T>(v8::Handle<T> value) for use in place of
- *      v8::Local<T>::New(...) since v8 started requiring isolate in Node 0.11.9
- *
- *  * 0.5.2 Nov 16 2013
- *    - Convert SavePersistent and GetFromPersistent in NanAsyncWorker from protected and public
- *
- *  * 0.5.1 Nov 12 2013
- *    - Use node::MakeCallback() instead of direct v8::Function::Call()
- *
- *  * 0.5.0 Nov 11 2013
- *    - Added @TooTallNate as collaborator
- *    - New, much simpler, "include_dirs" for binding.gyp
- *    - Added full range of NAN_INDEX_* macros to match NAN_PROPERTY_* macros
- *
- *  * 0.4.4 Nov 2 2013
- *    - Isolate argument from v8::Persistent::MakeWeak removed for 0.11.8+
- *
- *  * 0.4.3 Nov 2 2013
- *    - Include node_object_wrap.h, removed from node.h for Node 0.11.8.
- *
- *  * 0.4.2 Nov 2 2013
- *    - Handle deprecation of v8::Persistent::Dispose(v8::Isolate* isolate)) for
- *      Node 0.11.8 release.
- *
- *  * 0.4.1 Sep 16 2013
- *    - Added explicit `#include <uv.h>` as it was removed from node.h for v0.11.8
- *
- *  * 0.4.0 Sep 2 2013
- *    - Added NAN_INLINE and NAN_DEPRECATED and made use of them
- *    - Added NanError, NanTypeError and NanRangeError
- *    - Cleaned up code
- *
- *  * 0.3.2 Aug 30 2013
- *    - Fix missing scope declaration in GetFromPersistent() and SaveToPersistent
- *      in NanAsyncWorker
- *
- *  * 0.3.1 Aug 20 2013
- *    - fix "not all control paths return a value" compile warning on some platforms
- *
- *  * 0.3.0 Aug 19 2013
- *    - Made NAN work with NPM
- *    - Lots of fixes to NanFromV8String, pulling in features from new Node core
- *    - Changed node::encoding to Nan::Encoding in NanFromV8String to unify the API
- *    - Added optional error number argument for NanThrowError()
- *    - Added NanInitPersistent()
- *    - Added NanReturnNull() and NanReturnEmptyString()
- *    - Added NanLocker and NanUnlocker
- *    - Added missing scopes
- *    - Made sure to clear disposed Persistent handles
- *    - Changed NanAsyncWorker to allocate error messages on the heap
- *    - Changed NanThrowError(Local<Value>) to NanThrowError(Handle<Value>)
- *    - Fixed leak in NanAsyncWorker when errmsg is used
- *
- *  * 0.2.2 Aug 5 2013
- *    - Fixed usage of undefined variable with node::BASE64 in NanFromV8String()
- *
- *  * 0.2.1 Aug 5 2013
- *    - Fixed 0.8 breakage, node::BUFFER encoding type not available in 0.8 for
- *      NanFromV8String()
- *
- *  * 0.2.0 Aug 5 2013
- *    - Added NAN_PROPERTY_GETTER, NAN_PROPERTY_SETTER, NAN_PROPERTY_ENUMERATOR,
- *      NAN_PROPERTY_DELETER, NAN_PROPERTY_QUERY
- *    - Extracted _NAN_METHOD_ARGS, _NAN_GETTER_ARGS, _NAN_SETTER_ARGS,
- *      _NAN_PROPERTY_GETTER_ARGS, _NAN_PROPERTY_SETTER_ARGS,
- *      _NAN_PROPERTY_ENUMERATOR_ARGS, _NAN_PROPERTY_DELETER_ARGS,
- *      _NAN_PROPERTY_QUERY_ARGS
- *    - Added NanGetInternalFieldPointer, NanSetInternalFieldPointer
- *    - Added NAN_WEAK_CALLBACK, NAN_WEAK_CALLBACK_OBJECT,
- *      NAN_WEAK_CALLBACK_DATA, NanMakeWeak
- *    - Renamed THROW_ERROR to _NAN_THROW_ERROR
- *    - Added NanNewBufferHandle(char*, size_t, node::smalloc::FreeCallback, void*)
- *    - Added NanBufferUse(char*, uint32_t)
- *    - Added NanNewContextHandle(v8::ExtensionConfiguration*,
- *        v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Value>)
- *    - Fixed broken NanCallback#GetFunction()
- *    - Added optional encoding and size arguments to NanFromV8String()
- *    - Added NanGetPointerSafe() and NanSetPointerSafe()
- *    - Added initial test suite (to be expanded)
- *    - Allow NanUInt32OptionValue to convert any Number object
- *
- *  * 0.1.0 Jul 21 2013
- *    - Added `NAN_GETTER`, `NAN_SETTER`
- *    - Added `NanThrowError` with single Local<Value> argument
- *    - Added `NanNewBufferHandle` with single uint32_t argument
- *    - Added `NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>)`
- *    - Added `Local<Function> NanCallback#GetFunction()`
- *    - Added `NanCallback#Call(int, Local<Value>[])`
- *    - Deprecated `NanCallback#Run(int, Local<Value>[])` in favour of Call
+ * Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30
  *
  * See https://github.com/rvagg/nan for the latest update to this file
  **********************************************************************************/
@@ -180,6 +25,8 @@
 #include <node_version.h>
 #include <node_object_wrap.h>
 #include <string.h>
+#include <limits.h>
+#include <string>
 
 #if defined(__GNUC__) && !defined(DEBUG)
 # define NAN_INLINE inline __attribute__((always_inline))
@@ -578,6 +425,12 @@ NAN_INLINE uint32_t NanUInt32OptionValue(
   }
 
   template<>
+  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>(
+      std::string arg) {
+    return NanNew<v8::String>(arg.c_str(), arg.size());
+  }
+
+  template<>
   NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() {
     return v8::String::Empty(v8::Isolate::GetCurrent());
   }
@@ -598,6 +451,11 @@ NAN_INLINE uint32_t NanUInt32OptionValue(
     return NanNew<v8::String>(arg, length);
   }
 
+  NAN_INLINE v8::Local<v8::String> NanNew(
+      const std::string& arg) {
+    return NanNew<v8::String>(arg.c_str(), arg.size());
+  }
+
   NAN_INLINE v8::Local<v8::Number> NanNew(double val) {
     return NanNew<v8::Number>(val);
   }
@@ -669,7 +527,8 @@ NAN_INLINE uint32_t NanUInt32OptionValue(
   }
 
   NAN_INLINE int NanAdjustExternalMemory(int bc) {
-    return v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc);
+    return static_cast<int>(
+        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
   }
 
   NAN_INLINE void NanSetTemplate(
@@ -678,7 +537,14 @@ NAN_INLINE uint32_t NanUInt32OptionValue(
     , v8::Handle<v8::Data> value) {
     templ->Set(v8::Isolate::GetCurrent(), name, value);
   }
-  
+
+  NAN_INLINE void NanSetTemplate(
+      v8::Handle<v8::Template> templ
+    , v8::Handle<v8::String> name
+    , v8::Handle<v8::Data> value
+    , v8::PropertyAttribute attributes) {
+    templ->Set(name, value, attributes);
+  }
 
   NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
     return v8::Isolate::GetCurrent()->GetCurrentContext();
@@ -966,6 +832,112 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
         v8::Isolate::GetCurrent(), target, func, argc, argv));
   }
 
+  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
+      v8::Handle<v8::Object> target
+    , v8::Handle<v8::String> symbol
+    , int argc
+    , v8::Handle<v8::Value>* argv) {
+    return NanNew(node::MakeCallback(
+        v8::Isolate::GetCurrent(), target, symbol, argc, argv));
+  }
+
+  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
+      v8::Handle<v8::Object> target
+    , const char* method
+    , int argc
+    , v8::Handle<v8::Value>* argv) {
+    return NanNew(node::MakeCallback(
+        v8::Isolate::GetCurrent(), target, method, argc, argv));
+  }
+
+  template<typename T>
+  NAN_INLINE void NanSetIsolateData(
+      v8::Isolate *isolate
+    , T *data
+  ) {
+      isolate->SetData(0, data);
+  }
+
+  template<typename T>
+  NAN_INLINE T *NanGetIsolateData(
+      v8::Isolate *isolate
+  ) {
+      return static_cast<T*>(isolate->GetData(0));
+  }
+
+  class NanAsciiString {
+   public:
+    NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
+      v8::Local<v8::String> toStr = from->ToString();
+      int buf_size = toStr->Length() + 1;
+      buf = new char[buf_size];
+      size = toStr->WriteOneByte(
+          reinterpret_cast<unsigned char*>(buf), 0, buf_size);
+    }
+
+    NAN_INLINE int Size() const {
+      return size;
+    }
+
+    NAN_INLINE char* operator*() { return buf; }
+
+    NAN_INLINE ~NanAsciiString() {
+      delete[] buf;
+    }
+
+   private:
+    char *buf;
+    int size;
+  };
+
+  class NanUtf8String {
+   public:
+    NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
+      v8::Local<v8::String> toStr = from->ToString();
+      int buf_size = toStr->Utf8Length() + 1;
+      buf = new char[buf_size];
+      size = toStr->WriteUtf8(buf, buf_size);
+    }
+
+    NAN_INLINE int Size() const {
+      return size;
+    }
+
+    NAN_INLINE char* operator*() { return buf; }
+
+    NAN_INLINE ~NanUtf8String() {
+      delete[] buf;
+    }
+
+   private:
+    char *buf;
+    int size;
+  };
+
+  class NanUcs2String {
+   public:
+    NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
+      v8::Local<v8::String> toStr = from->ToString();
+      int buf_size = toStr->Length() + 1;
+      buf = new uint16_t[buf_size];
+      size = toStr->Write(buf, 0, buf_size);
+    }
+
+    NAN_INLINE int Size() const {
+      return size;
+    }
+
+    NAN_INLINE uint16_t* operator*() { return buf; }
+
+    NAN_INLINE ~NanUcs2String() {
+      delete[] buf;
+    }
+
+   private:
+    uint16_t *buf;
+    int size;
+  };
+
 #else
 // Node 0.8 and 0.10
 
@@ -1103,7 +1075,6 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
     return v8::Array::New(length);
   }
 
-
   template<>
   NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) {
     return v8::Date::New(time).As<v8::Date>();
@@ -1182,7 +1153,9 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
     , int length) {
     int len = length;
     if (len < 0) {
-      len = strlen(reinterpret_cast<const char *>(arg));
+      size_t temp = strlen(reinterpret_cast<const char *>(arg));
+      assert(temp <= INT_MAX && "too long string");
+      len = static_cast<int>(temp);
     }
     uint16_t *warg = new uint16_t[len];
     for (int i = 0; i < len; i++) {
@@ -1199,7 +1172,9 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
     , int length) {
     int len = length;
     if (len < 0) {
-      len = strlen(reinterpret_cast<const char *>(arg));
+      size_t temp = strlen(reinterpret_cast<const char *>(arg));
+      assert(temp <= INT_MAX && "too long string");
+      len = static_cast<int>(temp);
     }
     uint16_t *warg = new uint16_t[len];
     for (int i = 0; i < len; i++) {
@@ -1212,7 +1187,9 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
 
   template<>
   NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) {
-    int length = strlen(reinterpret_cast<char *>(arg));
+    size_t temp = strlen(reinterpret_cast<char *>(arg));
+    assert(temp <= INT_MAX && "too long string");
+    int length = static_cast<int>(temp);
     uint16_t *warg = new uint16_t[length];
     for (int i = 0; i < length; i++) {
       warg[i] = arg[i];
@@ -1226,7 +1203,9 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
   template<>
   NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
       const uint8_t *arg) {
-    int length = strlen(reinterpret_cast<const char *>(arg));
+    size_t temp = strlen(reinterpret_cast<const char *>(arg));
+    assert(temp <= INT_MAX && "too long string");
+    int length = static_cast<int>(temp);
     uint16_t *warg = new uint16_t[length];
     for (int i = 0; i < length; i++) {
       warg[i] = arg[i];
@@ -1237,6 +1216,12 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
   }
 
   template<>
+  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>(
+      std::string arg) {
+    return NanNew<v8::String>(arg.c_str(), arg.size());
+  }
+
+  template<>
   NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() {
     return v8::String::Empty();
   }
@@ -1257,6 +1242,11 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
     return NanNew<v8::String>(arg, length);
   }
 
+  NAN_INLINE v8::Local<v8::String> NanNew(
+      std::string& arg) {
+    return NanNew<v8::String>(arg.c_str(), arg.size());
+  }
+
   NAN_INLINE v8::Local<v8::Number> NanNew(double val) {
     return NanNew<v8::Number>(val);
   }
@@ -1315,7 +1305,7 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
   }
 
   NAN_INLINE int NanAdjustExternalMemory(int bc) {
-    return v8::V8::AdjustAmountOfExternalAllocatedMemory(bc);
+    return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
   }
 
   NAN_INLINE void NanSetTemplate(
@@ -1324,7 +1314,14 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
     , v8::Handle<v8::Data> value) {
     templ->Set(name, value);
   }
-  
+
+  NAN_INLINE void NanSetTemplate(
+      v8::Handle<v8::Template> templ
+    , v8::Handle<v8::String> name
+    , v8::Handle<v8::Data> value
+    , v8::PropertyAttribute attributes) {
+    templ->Set(name, value, attributes);
+  }
 
   NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
     return v8::Context::GetCurrent();
@@ -1621,6 +1618,118 @@ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
 # endif
   }
 
+  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
+      v8::Handle<v8::Object> target
+    , v8::Handle<v8::String> symbol
+    , int argc
+    , v8::Handle<v8::Value>* argv) {
+# if NODE_VERSION_AT_LEAST(0, 8, 0)
+    return NanNew(node::MakeCallback(target, symbol, argc, argv));
+# else
+    v8::Local<v8::Function> callback = target->Get(symbol).As<v8::Function>();
+    return NanMakeCallback(target, callback, argc, argv);
+# endif
+  }
+
+  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
+      v8::Handle<v8::Object> target
+    , const char* method
+    , int argc
+    , v8::Handle<v8::Value>* argv) {
+# if NODE_VERSION_AT_LEAST(0, 8, 0)
+    return NanNew(node::MakeCallback(target, method, argc, argv));
+# else
+    return NanMakeCallback(target, NanNew(method), argc, argv);
+# endif
+  }
+
+  template<typename T>
+  NAN_INLINE void NanSetIsolateData(
+      v8::Isolate *isolate
+    , T *data
+  ) {
+      isolate->SetData(data);
+  }
+
+  template<typename T>
+  NAN_INLINE T *NanGetIsolateData(
+      v8::Isolate *isolate
+  ) {
+      return static_cast<T*>(isolate->GetData());
+  }
+
+  class NanAsciiString {
+   public:
+    NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
+      v8::Local<v8::String> toStr = from->ToString();
+      int buf_size = toStr->Length() + 1;
+      buf = new char[buf_size];
+      size = toStr->WriteAscii(buf, 0, buf_size);
+    }
+
+    NAN_INLINE int Size() const {
+      return size;
+    }
+
+    NAN_INLINE char* operator*() { return buf; }
+
+    NAN_INLINE ~NanAsciiString() {
+      delete[] buf;
+    }
+
+   private:
+    char *buf;
+    int size;
+  };
+
+  class NanUtf8String {
+   public:
+    NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
+      v8::Local<v8::String> toStr = from->ToString();
+      int buf_size = toStr->Utf8Length() + 1;
+      buf = new char[buf_size];
+      size = toStr->WriteUtf8(buf, buf_size);
+    }
+
+    NAN_INLINE int Size() const {
+      return size;
+    }
+
+    NAN_INLINE char* operator*() { return buf; }
+
+    NAN_INLINE ~NanUtf8String() {
+      delete[] buf;
+    }
+
+   private:
+    char *buf;
+    int size;
+  };
+
+  class NanUcs2String {
+   public:
+    NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
+      v8::Local<v8::String> toStr = from->ToString();
+      int buf_size = toStr->Length() + 1;
+      buf = new uint16_t[buf_size];
+      size = toStr->Write(buf, 0, buf_size);
+    }
+
+    NAN_INLINE int Size() const {
+      return size;
+    }
+
+    NAN_INLINE uint16_t* operator*() { return buf; }
+
+    NAN_INLINE ~NanUcs2String() {
+      delete[] buf;
+    }
+
+   private:
+    uint16_t *buf;
+    int size;
+  };
+
 #endif  // NODE_MODULE_VERSION
 
 typedef void (*NanFreeCallback)(char *data, void *hint);
@@ -1706,33 +1815,34 @@ class NanCallback {
     return NanNew(handle)->Get(kCallbackIndex)->IsUndefined();
   }
 
-  void Call(int argc, v8::Handle<v8::Value> argv[]) const {
-    NanScope();
+  v8::Handle<v8::Value> Call(int argc, v8::Handle<v8::Value> argv[]) const {
+    NanEscapableScope();
 #if (NODE_MODULE_VERSION > 0x000B)  // 0.11.12+
     v8::Isolate* isolate = v8::Isolate::GetCurrent();
     v8::Local<v8::Function> callback = NanNew(handle)->
         Get(kCallbackIndex).As<v8::Function>();
-    node::MakeCallback(
+    return NanEscapeScope(node::MakeCallback(
         isolate
       , isolate->GetCurrentContext()->Global()
       , callback
       , argc
       , argv
-    );
+    ));
 #else
 #if NODE_VERSION_AT_LEAST(0, 8, 0)
     v8::Local<v8::Function> callback = handle->
         Get(kCallbackIndex).As<v8::Function>();
-    node::MakeCallback(
+    return NanEscapeScope(node::MakeCallback(
         v8::Context::GetCurrent()->Global()
       , callback
       , argc
       , argv
-    );
+    ));
 #else
     v8::Local<v8::Function> callback = handle->
         Get(kCallbackIndex).As<v8::Function>();
-    NanMakeCallback(v8::Context::GetCurrent()->Global(), callback, argc, argv);
+    return NanEscapeScope(NanMakeCallback(
+        v8::Context::GetCurrent()->Global(), callback, argc, argv));
 #endif
 #endif
   }
@@ -2012,7 +2122,7 @@ namespace Nan {
   enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
 }
 
-NAN_INLINE void* NanRawString(
+/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString(
     v8::Handle<v8::Value> from
   , enum Nan::Encoding encoding
   , size_t *datalen
@@ -2160,7 +2270,19 @@ NAN_INLINE void* NanRawString(
   return to;
 }
 
-NAN_INLINE char* NanCString(
+NAN_DEPRECATED NAN_INLINE void* NanRawString(
+    v8::Handle<v8::Value> from
+  , enum Nan::Encoding encoding
+  , size_t *datalen
+  , void *buf
+  , size_t buflen
+  , int flags
+) {
+  return _NanRawString(from, encoding, datalen, buf, buflen, flags);
+}
+
+
+NAN_DEPRECATED NAN_INLINE char* NanCString(
     v8::Handle<v8::Value> from
   , size_t *datalen
   , char *buf = NULL
@@ -2168,7 +2290,7 @@ NAN_INLINE char* NanCString(
   , int flags = v8::String::NO_OPTIONS
 ) {
     return static_cast<char *>(
-      NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags)
+      _NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags)
     );
 }
 
@@ -2177,7 +2299,33 @@ NAN_INLINE void NanSetPrototypeTemplate(
   , const char *name
   , v8::Handle<v8::Data> value
 ) {
-    NanSetTemplate(templ->PrototypeTemplate(), name, value);
+  NanSetTemplate(templ->PrototypeTemplate(), name, value);
+}
+
+NAN_INLINE void NanSetPrototypeTemplate(
+    v8::Local<v8::FunctionTemplate> templ
+  , v8::Handle<v8::String> name
+  , v8::Handle<v8::Data> value
+  , v8::PropertyAttribute attributes
+) {
+  NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes);
+}
+
+NAN_INLINE void NanSetInstanceTemplate(
+    v8::Local<v8::FunctionTemplate> templ
+  , const char *name
+  , v8::Handle<v8::Data> value
+) {
+  NanSetTemplate(templ->InstanceTemplate(), name, value);
+}
+
+NAN_INLINE void NanSetInstanceTemplate(
+    v8::Local<v8::FunctionTemplate> templ
+  , v8::Handle<v8::String> name
+  , v8::Handle<v8::Data> value
+  , v8::PropertyAttribute attributes
+) {
+  NanSetTemplate(templ->InstanceTemplate(), name, value, attributes);
 }
 
 #endif  // NAN_H_
diff --git a/package.json b/package.json
index 4785560..a6488db 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,16 @@
 {
   "name": "nan",
-  "version": "1.2.0",
+  "version": "1.3.0",
   "description": "Native Abstractions for Node.js: C++ header for Node 0.8->0.12 compatibility",
   "main": "include_dirs.js",
   "repository": {
     "type": "git",
     "url": "git://github.com/rvagg/nan.git"
   },
+  "scripts": {
+    "test": "tap --gc test/js/*-test.js",
+    "rebuild-tests": "node-gyp rebuild --directory test"
+  },
   "contributors": [
     "Rod Vagg <r at va.gg> (https://github.com/rvagg)",
     "Benjamin Byholm <bbyholm at abo.fi> (https://github.com/kkoopa/)",
@@ -15,5 +19,11 @@
     "Brett Lawson <brett19 at gmail.com> (https://github.com/brett19)",
     "Ben Noordhuis <info at bnoordhuis.nl> (https://github.com/bnoordhuis)"
   ],
+  "devDependencies": {
+    "bindings": "~1.2.1",
+    "node-gyp": "~1.0.1",
+    "tap": "~0.4.12",
+    "xtend": "~4.0.0"
+  },
   "license": "MIT"
 }
diff --git a/test/binding.gyp b/test/binding.gyp
index 0ca5ecf..062d75d 100644
--- a/test/binding.gyp
+++ b/test/binding.gyp
@@ -117,4 +117,18 @@
             "<!(node -e \"require('..')\")"
         ]
     }
+    , {
+        "target_name" : "makecallback"
+      , "sources"     : [ "cpp/makecallback.cpp" ]
+      , "include_dirs": [
+            "<!(node -e \"require('..')\")"
+        ]
+    }
+    , {
+        "target_name" : "isolatedata"
+      , "sources"     : [ "cpp/isolatedata.cpp" ]
+      , "include_dirs": [
+            "<!(node -e \"require('..')\")"
+        ]
+    }
 ]}
diff --git a/test/cpp/isolatedata.cpp b/test/cpp/isolatedata.cpp
new file mode 100644
index 0000000..5a6c9c7
--- /dev/null
+++ b/test/cpp/isolatedata.cpp
@@ -0,0 +1,38 @@
+/**********************************************************************************
+ * NAN - Native Abstractions for Node.js
+ *
+ * Copyright (c) 2014 NAN contributors
+ *
+ * MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/LICENSE>
+ **********************************************************************************/
+
+#include <nan.h>
+
+struct Dummy {
+  int value;
+};
+
+NAN_METHOD(SetAndGet) {
+  NanScope();
+
+  Dummy *d0 = new Dummy;
+  Dummy *d1 = NULL;
+
+  v8::Isolate *isolate = v8::Isolate::GetCurrent();
+
+  NanSetIsolateData<Dummy>(isolate, d0);
+  d1 = NanGetIsolateData<Dummy>(isolate);
+
+  delete d1;
+
+  NanReturnValue(NanNew<v8::Boolean>(d0 == d1));
+}
+
+void Init (v8::Handle<v8::Object> target) {
+  target->Set(
+      NanNew<v8::String>("setAndGet")
+    , NanNew<v8::FunctionTemplate>(SetAndGet)->GetFunction()
+  );
+}
+
+NODE_MODULE(isolatedata, Init)
diff --git a/test/cpp/makecallback.cpp b/test/cpp/makecallback.cpp
new file mode 100644
index 0000000..d65c446
--- /dev/null
+++ b/test/cpp/makecallback.cpp
@@ -0,0 +1,74 @@
+/**********************************************************************************
+* NAN - Native Abstractions for Node.js
+*
+* Copyright (c) 2014 NAN contributors
+*
+* MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/LICENSE>
+**********************************************************************************/
+
+#include <nan.h>
+
+class MyObject : public node::ObjectWrap {
+public:
+    static void Init(v8::Handle<v8::Object> exports);
+
+private:
+    MyObject();
+    ~MyObject();
+
+    static NAN_METHOD(New);
+    static NAN_METHOD(CallEmit);
+    static v8::Persistent<v8::Function> constructor;
+};
+
+v8::Persistent<v8::Function> MyObject::constructor;
+
+MyObject::MyObject() {
+}
+
+MyObject::~MyObject() {
+}
+
+void MyObject::Init(v8::Handle<v8::Object> exports) {
+    NanScope();
+
+    // Prepare constructor template
+    v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
+    tpl->SetClassName(NanNew<v8::String>("MyObject"));
+    tpl->InstanceTemplate()->SetInternalFieldCount(1);
+
+    NODE_SET_PROTOTYPE_METHOD(tpl, "call_emit", CallEmit);
+
+    NanAssignPersistent<v8::Function>(constructor, tpl->GetFunction());
+    exports->Set(NanNew<v8::String>("MyObject"), tpl->GetFunction());
+}
+
+NAN_METHOD(MyObject::New) {
+    NanScope();
+
+    if (args.IsConstructCall()) {
+        MyObject* obj = new MyObject();
+        obj->Wrap(args.This());
+        NanReturnValue(args.This());
+    }
+    else {
+        v8::Local<v8::Function> cons = NanNew<v8::Function>(constructor);
+        NanReturnValue(cons->NewInstance());
+    }
+}
+
+NAN_METHOD(MyObject::CallEmit) {
+    NanScope();
+    v8::Handle<v8::Value> argv[1] = {
+        NanNew("event"), // event name
+    };
+
+    NanMakeCallback(args.This(), "emit", 1, argv);
+    NanReturnUndefined();
+}
+
+void Init(v8::Handle<v8::Object> exports) {
+    MyObject::Init(exports);
+}
+
+NODE_MODULE(makecallback, Init)
diff --git a/test/cpp/multifile2.cpp b/test/cpp/multifile2.cpp
index ed1a3ca..14d644d 100644
--- a/test/cpp/multifile2.cpp
+++ b/test/cpp/multifile2.cpp
@@ -10,8 +10,6 @@
 
 NAN_METHOD(ReturnString) {
   NanScope();
-  char *buf = NanCString(args[0], NULL);
-  v8::Local<v8::String> s = NanNew<v8::String>(buf);
-  delete[] buf;
+  v8::Local<v8::String> s = NanNew<v8::String>(*NanUtf8String(args[0]));
   NanReturnValue(s);
 }
diff --git a/test/cpp/news.cpp b/test/cpp/news.cpp
index c6e7fa6..488fc21 100644
--- a/test/cpp/news.cpp
+++ b/test/cpp/news.cpp
@@ -7,6 +7,7 @@
  **********************************************************************************/
 
 #include <nan.h>
+#include <string>
 
 static int magic = 1337;
 
@@ -59,7 +60,13 @@ NAN_METHOD(NewLatin1String) {
 
 NAN_METHOD(NewUcs2String) {
   NanScope();
-  uint16_t s[] = {'s', 't', 'r', 0xef, 'n', 'g', '\0'};
+  const uint16_t s[] = {'s', 't', 'r', 0xef, 'n', 'g', '\0'};
+  NanReturnValue(NanNew(s));
+}
+
+NAN_METHOD(NewStdString) {
+  NanScope();
+  const std::string s = "strïng";
   NanReturnValue(NanNew<v8::String>(s));
 }
 
@@ -179,6 +186,10 @@ void Init(v8::Handle<v8::Object> target) {
     , NanNew<v8::FunctionTemplate>(NewUcs2String)->GetFunction()
   );
   target->Set(
+      NanNew<v8::String>("newStdString")
+    , NanNew<v8::FunctionTemplate>(NewStdString)->GetFunction()
+  );
+  target->Set(
       NanNew<v8::String>("newRegExp")
     , NanNew<v8::FunctionTemplate>(NewRegExp)->GetFunction()
   );
diff --git a/test/cpp/settemplate.cpp b/test/cpp/settemplate.cpp
index 78cbedb..2845d57 100644
--- a/test/cpp/settemplate.cpp
+++ b/test/cpp/settemplate.cpp
@@ -37,7 +37,14 @@ void MyObject::Init(v8::Handle<v8::Object> exports) {
 	tpl->InstanceTemplate()->SetInternalFieldCount(1);
 
 	// Prototype
-	NanSetPrototypeTemplate(tpl, "test", NanNew<v8::String>("a prototype property"));
+	NanSetPrototypeTemplate(tpl, "prototypeProp", NanNew<v8::String>("a prototype property"));
+	// Instance
+	NanSetInstanceTemplate(tpl, "instanceProp", NanNew<v8::String>("an instance property"));
+	// PropertyAttributes
+	NanSetInstanceTemplate(tpl, NanNew<v8::String>("none"), NanNew<v8::String>("none"), v8::None);
+	NanSetInstanceTemplate(tpl, NanNew<v8::String>("readOnly"), NanNew<v8::String>("readOnly"), v8::ReadOnly);
+	NanSetInstanceTemplate(tpl, NanNew<v8::String>("dontEnum"), NanNew<v8::String>("dontEnum"), v8::DontEnum);
+	NanSetInstanceTemplate(tpl, NanNew<v8::String>("dontDelete"), NanNew<v8::String>("dontDelete"), v8::DontDelete);
 
 	NanAssignPersistent<v8::Function>(constructor, tpl->GetFunction());
 	exports->Set(NanNew<v8::String>("MyObject"), tpl->GetFunction());
diff --git a/test/cpp/settergetter.cpp b/test/cpp/settergetter.cpp
index 2544dc2..8fb44d9 100644
--- a/test/cpp/settergetter.cpp
+++ b/test/cpp/settergetter.cpp
@@ -7,7 +7,7 @@
  **********************************************************************************/
 
 #include <nan.h>
-#include <string>
+#include <cstring>
 
 class SetterGetter : public node::ObjectWrap {
  public:
@@ -21,9 +21,9 @@ class SetterGetter : public node::ObjectWrap {
 
   SetterGetter();
 
-  std::string log;
-  std::string prop1;
-  std::string prop2;
+  char log[1024];
+  char prop1[256];
+  char prop2[256];
 };
 
 static v8::Persistent<v8::FunctionTemplate> settergetter_constructor;
@@ -34,7 +34,10 @@ NAN_METHOD(CreateNew) {
 }
 
 SetterGetter::SetterGetter() {
-  prop1.assign("this is property 1");
+  log[0] = '\0';
+  strncpy(prop1, "this is property 1", sizeof (prop1) - 1);
+  prop1[sizeof (prop1) - 1] = '\0';
+  prop2[0] = '\0';
 }
 
 void SetterGetter::Init(v8::Handle<v8::Object> target) {
@@ -69,7 +72,11 @@ NAN_METHOD(SetterGetter::New) {
   NanScope();
 
   SetterGetter* settergetter = new SetterGetter();
-  settergetter->log.append("New()\n");
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , "New()\n"
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
   settergetter->Wrap(args.This());
 
   NanReturnValue(args.This());
@@ -80,11 +87,23 @@ NAN_GETTER(SetterGetter::GetProp1) {
 
   SetterGetter* settergetter =
     node::ObjectWrap::Unwrap<SetterGetter>(args.This());
-  settergetter->log.append("Prop1:GETTER(");
-  settergetter->log.append(settergetter->prop1);
-  settergetter->log.append(")\n");
-
-  NanReturnValue(NanNew<v8::String>(settergetter->prop1.c_str()));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , "Prop1:GETTER("
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , settergetter->prop1
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , ")\n"
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+
+  NanReturnValue(NanNew(settergetter->prop1));
 }
 
 NAN_GETTER(SetterGetter::GetProp2) {
@@ -92,22 +111,50 @@ NAN_GETTER(SetterGetter::GetProp2) {
 
   SetterGetter* settergetter =
     node::ObjectWrap::Unwrap<SetterGetter>(args.This());
-  settergetter->log.append("Prop2:GETTER(");
-  settergetter->log.append(settergetter->prop2);
-  settergetter->log.append(")\n");
-
-  NanReturnValue(NanNew<v8::String>(settergetter->prop2.c_str()));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , "Prop2:GETTER("
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , settergetter->prop2
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , ")\n"
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+
+  NanReturnValue(NanNew(settergetter->prop2));
 }
 
 NAN_SETTER(SetterGetter::SetProp2) {
   NanScope();
 
   SetterGetter* settergetter =
-    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
-    settergetter->prop2.assign(NanCString(value, NULL));
-  settergetter->log.append("Prop2:SETTER(");
-  settergetter->log.append(settergetter->prop2);
-  settergetter->log.append(")\n");
+      node::ObjectWrap::Unwrap<SetterGetter>(args.This());
+  strncpy(
+      settergetter->prop2
+    , *NanUtf8String(value)
+    , sizeof (settergetter->prop2));
+  settergetter->prop2[sizeof (settergetter->prop2) - 1] = '\0';
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , "Prop2:SETTER("
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , settergetter->prop2
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
+  assert(strlen(settergetter->log) < sizeof (settergetter->log));
+  strncat(
+      settergetter->log
+    , ")\n"
+    , sizeof (settergetter->log) - 1 - strlen(settergetter->log));
 }
 
 NAN_METHOD(SetterGetter::Log) {
@@ -116,7 +163,7 @@ NAN_METHOD(SetterGetter::Log) {
   SetterGetter* settergetter =
     node::ObjectWrap::Unwrap<SetterGetter>(args.This());
 
-  NanReturnValue(NanNew<v8::String>(settergetter->log.c_str()));
+  NanReturnValue(NanNew(settergetter->log));
 }
 
 NODE_MODULE(settergetter, SetterGetter::Init)
diff --git a/test/cpp/strings.cpp b/test/cpp/strings.cpp
index 82c28e4..84630c8 100644
--- a/test/cpp/strings.cpp
+++ b/test/cpp/strings.cpp
@@ -8,165 +8,87 @@
 
 #include <nan.h>
 
-NAN_METHOD(ReturnString) {
+NAN_METHOD(ReturnAsciiString) {
   NanScope();
-  Nan::Encoding enc = Nan::UTF8;
-  size_t bc;
-  int flags = v8::String::HINT_MANY_WRITES_EXPECTED
-                     | v8::String::NO_NULL_TERMINATION;
-
-  if (args[1]->IsUint32()) {
-    enc = (Nan::Encoding) args[1]->Uint32Value();
-  }
-
-  if (args[2]->IsUint32()) {
-    flags = args[2]->Uint32Value();
-  }
-
-  void *s = NanRawString(args[0], enc, &bc, NULL, 0, flags);
-  if (enc == Nan::UCS2) {
-    v8::Local<v8::String> retval = NanNew<v8::String>(static_cast<uint16_t *>(s)
-      , (flags & v8::String::NO_NULL_TERMINATION) ? bc / 2 : -1);
-    assert((bc & 1) == 0 && "UCS2 string byte count was not even");
-    NanReturnValue(retval);
-  } else {
-    NanReturnValue(
-      NanNew<v8::String>(
-          static_cast<char *>(s)
-        , (flags & v8::String::NO_NULL_TERMINATION) ? bc : -1)
-    );
-  }
+  NanReturnValue(NanNew(*NanAsciiString(args[0])));
 }
 
-NAN_METHOD(ReturnCString) {
+NAN_METHOD(ReturnUtf8String) {
   NanScope();
-
-  size_t bc;
-  char *s = NanCString(args[0], &bc);
-  v8::Local<v8::String> str = NanNew<v8::String>(s);
-  delete[] s;
-
-  NanReturnValue(str);
+  NanReturnValue(NanNew(*NanUtf8String(args[0])));
 }
 
-NAN_METHOD(CompareCStringToBuffer) {
+NAN_METHOD(ReturnUcs2String) {
   NanScope();
-
-  size_t expectedLen = node::Buffer::Length(args[1]->ToObject());
-  char* expectedChars = node::Buffer::Data(args[1]->ToObject());
-
-  size_t actualLen;
-  char* actualChars = NanCString(args[0], &actualLen);
-
-  if (actualLen != expectedLen) {
-    NanThrowError(NanNew<v8::String>("actual length != expected length"));
-    NanReturnUndefined();
-  }
-
-  if (actualChars[expectedLen] != '\0') {
-    NanThrowError(NanNew<v8::String>("should be null-terminated"));
-    NanReturnUndefined();
-  }
-
-  if (strncmp(actualChars, expectedChars, expectedLen) != 0) {
-    NanThrowError(NanNew<v8::String>("actual chars != expected chars"));
-    NanReturnUndefined();
-  }
-
-  NanReturnValue(NanNew<v8::Boolean>(true));
+  NanReturnValue(NanNew(*NanUcs2String(args[0])));
 }
 
-NAN_METHOD(CompareRawStringToBuffer) {
+NAN_METHOD(HeapString) {
   NanScope();
-
-  size_t expectedLen = node::Buffer::Length(args[1]->ToObject());
-  char* expectedChars = node::Buffer::Data(args[1]->ToObject());
-
-  size_t actualLen;
-  char* decoded = static_cast<char *>(
-    NanRawString(
-      args[0]
-    , Nan::BASE64
-    , &actualLen
-    , NULL
-    , 0
-    , v8::String::HINT_MANY_WRITES_EXPECTED
-    )
-  );
-  char *actualChars = new char[actualLen];
-  memcpy(actualChars, decoded, actualLen);
-  delete[] decoded;
-
-  if (actualLen != expectedLen) {
-    NanThrowError(NanNew<v8::String>("actual length != expected length"));
-    NanReturnUndefined();
-  }
-
-  /* this is silly, it could easily be a virgin, zeroed buffer we're inspecting
-  if (actualChars[expectedLen] == '\0') {
-    delete[] actualChars;
-    NanThrowError(NanNew<v8::String>("should not be null-terminated"));
-    NanReturnUndefined();
-  }*/
-
-  if (strncmp(actualChars, expectedChars, expectedLen) != 0) {
-    delete[] actualChars;
-    NanThrowError(NanNew<v8::String>("actual chars != expected chars"));
-    NanReturnUndefined();
-  }
-
-  delete[] actualChars;
-
-  NanReturnValue(NanNew<v8::Boolean>(true));
+  NanUcs2String *s = new NanUcs2String(args[0]);
+  v8::Local<v8::String> res = NanNew(**s);
+  delete s;
+  NanReturnValue(res);
 }
 
-v8::Persistent<v8::FunctionTemplate> returnString_persistent;
-v8::Persistent<v8::FunctionTemplate> returnCString_persistent;
-v8::Persistent<v8::FunctionTemplate> compareCStringToBuffer_persistent;
-v8::Persistent<v8::FunctionTemplate> compareRawStringToBuffer_persistent;
+v8::Persistent<v8::FunctionTemplate> returnAsciiString_persistent;
+v8::Persistent<v8::FunctionTemplate> returnUtf8String_persistent;
+v8::Persistent<v8::FunctionTemplate> returnUcs2String_persistent;
+v8::Persistent<v8::FunctionTemplate> heapString_persistent;
 
 void Init (v8::Handle<v8::Object> target) {
   NanScope();
 
-  v8::Local<v8::FunctionTemplate> returnString =
-    NanNew<v8::FunctionTemplate>(ReturnString);
+  v8::Local<v8::FunctionTemplate> returnAsciiString =
+    NanNew<v8::FunctionTemplate>(ReturnAsciiString);
+
   NanAssignPersistent(
-    returnString_persistent
-  , returnString
+    returnAsciiString_persistent
+  , returnAsciiString
   );
+
   target->Set(
-      NanNew<v8::String>("returnString")
-    , returnString->GetFunction()
+      NanNew("returnAsciiString")
+    , returnAsciiString->GetFunction()
   );
-  v8::Local<v8::FunctionTemplate> returnCString =
-    NanNew<v8::FunctionTemplate>(ReturnCString);
+
+  v8::Local<v8::FunctionTemplate> returnUtf8String =
+    NanNew<v8::FunctionTemplate>(ReturnUtf8String);
+
   NanAssignPersistent(
-    returnCString_persistent
-  , returnCString
+    returnUtf8String_persistent
+  , returnUtf8String
   );
+
   target->Set(
-      NanNew<v8::String>("returnCString")
-    , returnCString->GetFunction()
+      NanNew("returnUtf8String")
+    , returnUtf8String->GetFunction()
   );
-  v8::Local<v8::FunctionTemplate> compareCStringToBuffer =
-    NanNew<v8::FunctionTemplate>(CompareCStringToBuffer);
+
+  v8::Local<v8::FunctionTemplate> returnUcs2String =
+    NanNew<v8::FunctionTemplate>(ReturnUcs2String);
+
   NanAssignPersistent(
-    compareCStringToBuffer_persistent
-  , compareCStringToBuffer
+    returnUcs2String_persistent
+  , returnUcs2String
   );
+
   target->Set(
-      NanNew<v8::String>("compareCStringToBuffer")
-    , compareCStringToBuffer->GetFunction()
+      NanNew("returnUcs2String")
+    , returnUcs2String->GetFunction()
   );
-  v8::Local<v8::FunctionTemplate> compareRawStringToBuffer =
-    NanNew<v8::FunctionTemplate>(CompareRawStringToBuffer);
+
+  v8::Local<v8::FunctionTemplate> heapString =
+    NanNew<v8::FunctionTemplate>(HeapString);
+
   NanAssignPersistent(
-    compareRawStringToBuffer_persistent
-  , compareRawStringToBuffer
+    heapString_persistent
+  , heapString
   );
+
   target->Set(
-      NanNew<v8::String>("compareRawStringToBuffer")
-    , compareRawStringToBuffer->GetFunction()
+      NanNew("heapString")
+    , heapString->GetFunction()
   );
 }
 
diff --git a/test/js/asyncworker-test.js b/test/js/asyncworker-test.js
index 204f2fc..054b2d9 100644
--- a/test/js/asyncworker-test.js
+++ b/test/js/asyncworker-test.js
@@ -1,8 +1,9 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'asyncworker' });
 
 test('asyncworker', function (t) {
-  var worker = bindings('asyncworker').a
+  var worker = bindings.a
     , ticks  = 0
     , called = false
   t.type(worker, 'function')
@@ -14,7 +15,7 @@ test('asyncworker', function (t) {
   setTimeout(tick, 0)
   worker(200, function () {
     called = true
-    t.ok(ticks > 12, 'got plenty of ticks! (' + ticks + ')')
+    t.ok(ticks > 6, 'got plenty of ticks! (' + ticks + ')')
     t.end()
   })
 })
diff --git a/test/js/asyncworkererror-test.js b/test/js/asyncworkererror-test.js
index 7835317..c5462d8 100644
--- a/test/js/asyncworkererror-test.js
+++ b/test/js/asyncworkererror-test.js
@@ -1,8 +1,9 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'asyncworkererror' });
 
 test('asyncworkererror', function (t) {
-  var worker = bindings('asyncworkererror').a
+  var worker = bindings.a
   t.type(worker, 'function')
   worker(function (err) {
     t.ok(err)
diff --git a/test/js/bufferworkerpersistent-test.js b/test/js/bufferworkerpersistent-test.js
index 1ab3fd3..1efc9a0 100644
--- a/test/js/bufferworkerpersistent-test.js
+++ b/test/js/bufferworkerpersistent-test.js
@@ -1,9 +1,10 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
-    , crypto   = require('crypto')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'bufferworkerpersistent' })
+    , crypto   = require('crypto');
 
 test('bufferworkerpersistent', function (t) {
-  var worker = bindings('bufferworkerpersistent').a
+  var worker = bindings.a
     , called = false
     , buf    = crypto.randomBytes(256)
     , bufHex = buf.toString('hex')
@@ -11,9 +12,9 @@ test('bufferworkerpersistent', function (t) {
   t.type(worker, 'function')
 
   setTimeout(function () {
-    t.ok(called)
+    t.ok(called, 'callback fired')
     t.end()
-  }, 300)
+  }, 500)
 
   worker(200, buf, function (_buf) {
     called = true
diff --git a/test/js/isolatedata-test.js b/test/js/isolatedata-test.js
new file mode 100644
index 0000000..e5637ef
--- /dev/null
+++ b/test/js/isolatedata-test.js
@@ -0,0 +1,11 @@
+const test     = require('tap').test
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'isolatedata' });
+
+test('isolatedata', function (t) {
+  t.plan(2);
+
+  var isolatedata = bindings;
+  t.type(isolatedata.setAndGet, 'function');
+  t.ok(isolatedata.setAndGet);
+});
diff --git a/test/js/makecallback-test.js b/test/js/makecallback-test.js
new file mode 100644
index 0000000..b6e3607
--- /dev/null
+++ b/test/js/makecallback-test.js
@@ -0,0 +1,24 @@
+const test     = require('tap').test
+    , testRoot = require('path').resolve(__dirname, '..')
+    , MyObject = require('bindings')({ module_root: testRoot, bindings: 'makecallback' }).MyObject
+    , EventEmitter = require('events').EventEmitter;
+
+// extend prototype
+function inherits(target, source) {
+    for (var k in source.prototype) {
+        target.prototype[k] = source.prototype[k];
+    }
+}
+
+inherits(MyObject, EventEmitter);
+
+test('makecallback', function (t) {
+    t.plan(1);
+
+    var obj = new MyObject();
+    obj.on('event', function() {
+        t.ok(true);
+    });
+
+    obj.call_emit();
+});
diff --git a/test/js/morenews-test.js b/test/js/morenews-test.js
index 788aed5..47a580c 100644
--- a/test/js/morenews-test.js
+++ b/test/js/morenews-test.js
@@ -1,23 +1,24 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'morenews' });
 
 test('morenews', function (t) {
   t.plan(16);
-  t.type(bindings('morenews').newNumber, 'function');
-  t.type(bindings('morenews').newPositiveInteger, 'function');
-  t.type(bindings('morenews').newNegativeInteger, 'function');
-  t.type(bindings('morenews').newUtf8String, 'function');
-  t.type(bindings('morenews').newLatin1String, 'function');
-  t.type(bindings('morenews').newUcs2String, 'function');
-  t.type(bindings('morenews').newExternalStringResource, 'function');
-  t.type(bindings('morenews').newExternalAsciiStringResource, 'function');
+  t.type(bindings.newNumber, 'function');
+  t.type(bindings.newPositiveInteger, 'function');
+  t.type(bindings.newNegativeInteger, 'function');
+  t.type(bindings.newUtf8String, 'function');
+  t.type(bindings.newLatin1String, 'function');
+  t.type(bindings.newUcs2String, 'function');
+  t.type(bindings.newExternalStringResource, 'function');
+  t.type(bindings.newExternalAsciiStringResource, 'function');
 
-  t.equal(bindings('morenews').newNumber(), 0.5);
-  t.equal(bindings('morenews').newPositiveInteger(), 1);
-  t.equal(bindings('morenews').newNegativeInteger(), -1);
-  t.equal(bindings('morenews').newUtf8String(), 'strïng');
-  t.equal(bindings('morenews').newLatin1String(), 'strïng');
-  t.equal(bindings('morenews').newUcs2String(), 'strïng');
-  t.equals(bindings('morenews').newExternalStringResource(), 'strïng');
-  t.equals(bindings('morenews').newExternalAsciiStringResource(), 'string');
+  t.equal(bindings.newNumber(), 0.5);
+  t.equal(bindings.newPositiveInteger(), 1);
+  t.equal(bindings.newNegativeInteger(), -1);
+  t.equal(bindings.newUtf8String(), 'strïng');
+  t.equal(bindings.newLatin1String(), 'strïng');
+  t.equal(bindings.newUcs2String(), 'strïng');
+  t.equals(bindings.newExternalStringResource(), 'strïng');
+  t.equals(bindings.newExternalAsciiStringResource(), 'string');
 });
diff --git a/test/js/multifile-test.js b/test/js/multifile-test.js
index 8d8beda..a9b17c9 100644
--- a/test/js/multifile-test.js
+++ b/test/js/multifile-test.js
@@ -1,5 +1,6 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'multifile' });
 
 // same as fromv8string test but split over multiple compile units
 // just to test that there aren't any conflicts from including nan.h
@@ -7,7 +8,7 @@ const test     = require('tap').test
 test('multifile', function (t) {
   t.plan(2);
 
-  var r = bindings('multifile').r
+  var r = bindings.r
   t.type(r, 'function');
   t.equal(r('a string value'), 'a string value');
 });
diff --git a/test/js/news-test.js b/test/js/news-test.js
index 32cda35..ffdfb51 100644
--- a/test/js/news-test.js
+++ b/test/js/news-test.js
@@ -1,51 +1,54 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'news' });
 
 test('news', function (t) {
-  t.plan(44);
-  t.type(bindings('news').newNumber, 'function');
-  t.type(bindings('news').newPositiveInteger, 'function');
-  t.type(bindings('news').newNegativeInteger, 'function');
-  t.type(bindings('news').newInt32FromPositive, 'function');
-  t.type(bindings('news').newInt32FromNegative, 'function');
-  t.type(bindings('news').newUint32FromPositive, 'function');
-  t.type(bindings('news').newUint32FromNegative, 'function');
-  t.type(bindings('news').newUtf8String, 'function');
-  t.type(bindings('news').newLatin1String, 'function');
-  t.type(bindings('news').newUcs2String, 'function');
-  t.type(bindings('news').newRegExp, 'function');
-  t.type(bindings('news').newStringObject, 'function');
-  t.type(bindings('news').newNumberObject, 'function');
-  t.type(bindings('news').newBooleanObject, 'function');
-  t.type(bindings('news').newExternal, 'function');
-  t.type(bindings('news').newSignature, 'function');
-  t.type(bindings('news').newScript, 'function');
-  t.type(bindings('news').newScript2, 'function');
-  t.type(bindings('news').compileScript, 'function');
-  t.type(bindings('news').compileScript2, 'function');
-  t.type(bindings('news').newDate, 'function');
-  t.type(bindings('news').newArray, 'function');
+  t.plan(46);
+  t.type(bindings.newNumber, 'function');
+  t.type(bindings.newPositiveInteger, 'function');
+  t.type(bindings.newNegativeInteger, 'function');
+  t.type(bindings.newInt32FromPositive, 'function');
+  t.type(bindings.newInt32FromNegative, 'function');
+  t.type(bindings.newUint32FromPositive, 'function');
+  t.type(bindings.newUint32FromNegative, 'function');
+  t.type(bindings.newUtf8String, 'function');
+  t.type(bindings.newLatin1String, 'function');
+  t.type(bindings.newUcs2String, 'function');
+  t.type(bindings.newStdString, 'function');
+  t.type(bindings.newRegExp, 'function');
+  t.type(bindings.newStringObject, 'function');
+  t.type(bindings.newNumberObject, 'function');
+  t.type(bindings.newBooleanObject, 'function');
+  t.type(bindings.newExternal, 'function');
+  t.type(bindings.newSignature, 'function');
+  t.type(bindings.newScript, 'function');
+  t.type(bindings.newScript2, 'function');
+  t.type(bindings.compileScript, 'function');
+  t.type(bindings.compileScript2, 'function');
+  t.type(bindings.newDate, 'function');
+  t.type(bindings.newArray, 'function');
 
-  t.equal(bindings('news').newNumber(), 0.5);
-  t.equal(bindings('news').newPositiveInteger(), 1);
-  t.equal(bindings('news').newNegativeInteger(), -1);
-  t.equal(bindings('news').newInt32FromPositive(), -1);
-  t.equal(bindings('news').newInt32FromNegative(), -1);
-  t.equal(bindings('news').newUint32FromPositive(), 0xFFFFFFFF);
-  t.equal(bindings('news').newUint32FromNegative(), 0xFFFFFFFF);
-  t.equal(bindings('news').newUtf8String(), 'strïng');
-  t.equal(bindings('news').newLatin1String(), 'strïng');
-  t.equal(bindings('news').newUcs2String(), 'strïng');
-  t.deepEquals(bindings('news').newRegExp(), /foo/g);
-  t.deepEquals(bindings('news').newStringObject(), new String("foo"));
-  t.deepEquals(bindings('news').newNumberObject(), new Number(0.5));
-  t.deepEquals(bindings('news').newBooleanObject(), new Boolean(true));
-  t.equals(bindings('news').newExternal(), 'passed');
-  t.equals(bindings('news').newSignature(), 'string');
-  t.equals(bindings('news').newScript(), 6);
-  t.equals(bindings('news').newScript2(), 6);
-  t.equals(bindings('news').compileScript(), 6);
-  t.equals(bindings('news').compileScript2(), 6);
-  t.deepEquals(bindings('news').newDate(), new Date(1337));
-  t.deepEquals(bindings('news').newArray(), []);
+  t.equal(bindings.newNumber(), 0.5);
+  t.equal(bindings.newPositiveInteger(), 1);
+  t.equal(bindings.newNegativeInteger(), -1);
+  t.equal(bindings.newInt32FromPositive(), -1);
+  t.equal(bindings.newInt32FromNegative(), -1);
+  t.equal(bindings.newUint32FromPositive(), 0xFFFFFFFF);
+  t.equal(bindings.newUint32FromNegative(), 0xFFFFFFFF);
+  t.equal(bindings.newUtf8String(), 'strïng');
+  t.equal(bindings.newLatin1String(), 'strïng');
+  t.equal(bindings.newUcs2String(), 'strïng');
+  t.equal(bindings.newStdString(), 'strïng');
+  t.deepEquals(bindings.newRegExp(), /foo/g);
+  t.deepEquals(bindings.newStringObject(), new String("foo"));
+  t.deepEquals(bindings.newNumberObject(), new Number(0.5));
+  t.deepEquals(bindings.newBooleanObject(), new Boolean(true));
+  t.equals(bindings.newExternal(), 'passed');
+  t.equals(bindings.newSignature(), 'string');
+  t.equals(bindings.newScript(), 6);
+  t.equals(bindings.newScript2(), 6);
+  t.equals(bindings.compileScript(), 6);
+  t.equals(bindings.compileScript2(), 6);
+  t.deepEquals(bindings.newDate(), new Date(1337));
+  t.deepEquals(bindings.newArray(), []);
 });
diff --git a/test/js/optionvalues-test.js b/test/js/optionvalues-test.js
index 521038b..3fd8bf8 100644
--- a/test/js/optionvalues-test.js
+++ b/test/js/optionvalues-test.js
@@ -1,5 +1,6 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'optionvalues' })
     , xtend    = require('xtend');
 
 test('optionvalues', function (t) {
@@ -18,7 +19,7 @@ test('optionvalues', function (t) {
       })
     , actobj;
 
-  t.type(bindings('optionvalues').o, 'function');
-  actobj = bindings('optionvalues').o(obj);
+  t.type(bindings.o, 'function');
+  actobj = bindings.o(obj);
   t.deepEqual(actobj, expobj);
 });
diff --git a/test/js/persistent-test.js b/test/js/persistent-test.js
index 6d877a8..16c6692 100644
--- a/test/js/persistent-test.js
+++ b/test/js/persistent-test.js
@@ -1,10 +1,11 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'persistent' });
 
 test('persistent', function (t) {
   t.plan(9)
 
-  var persistent = bindings('persistent')
+  var persistent = bindings;
   t.type(persistent.save1, 'function');
   t.type(persistent.get1, 'function');
   t.type(persistent.dispose1, 'function');
diff --git a/test/js/returnemptystring-test.js b/test/js/returnemptystring-test.js
index 053f170..1be1edb 100644
--- a/test/js/returnemptystring-test.js
+++ b/test/js/returnemptystring-test.js
@@ -1,9 +1,10 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'returnemptystring' });
 
 test('returnemptystring', function (t) {
   t.plan(3);
-  t.type(bindings('returnemptystring').r, 'function');
-  t.equal(bindings('returnemptystring').r('a string value'), '');
-  t.equal(bindings('returnemptystring').r(), '');
+  t.type(bindings.r, 'function');
+  t.equal(bindings.r('a string value'), '');
+  t.equal(bindings.r(), '');
 });
diff --git a/test/js/returnnull-test.js b/test/js/returnnull-test.js
index 5046e27..db2d596 100644
--- a/test/js/returnnull-test.js
+++ b/test/js/returnnull-test.js
@@ -1,9 +1,10 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'returnnull' });
 
 test('returnnull', function (t) {
   t.plan(3);
-  t.type(bindings('returnnull').r, 'function');
-  t.equal(bindings('returnnull').r('a string value'), null);
-  t.equal(bindings('returnnull').r(), null);
+  t.type(bindings.r, 'function');
+  t.equal(bindings.r('a string value'), null);
+  t.equal(bindings.r(), null);
 });
diff --git a/test/js/returnundefined-test.js b/test/js/returnundefined-test.js
index fa1bc5c..ab1549f 100644
--- a/test/js/returnundefined-test.js
+++ b/test/js/returnundefined-test.js
@@ -1,9 +1,10 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'returnundefined' });
 
 test('returnundefined', function (t) {
   t.plan(3);
-  t.type(bindings('returnundefined').r, 'function');
-  t.equal(bindings('returnundefined').r('a string value'), undefined);
-  t.equal(bindings('returnundefined').r(), undefined);
+  t.type(bindings.r, 'function');
+  t.equal(bindings.r('a string value'), undefined);
+  t.equal(bindings.r(), undefined);
 });
diff --git a/test/js/returnvalue-test.js b/test/js/returnvalue-test.js
index 5425cf3..b2a3034 100644
--- a/test/js/returnvalue-test.js
+++ b/test/js/returnvalue-test.js
@@ -1,9 +1,10 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'returnvalue' });
 
 test('returnvalue', function (t) {
   t.plan(3);
-  t.type(bindings('returnvalue').r, 'function');
-  t.equal(bindings('returnvalue').r('a string value'), 'a string value');
-  t.equal(bindings('returnvalue').r(), 'default');
+  t.type(bindings.r, 'function');
+  t.equal(bindings.r('a string value'), 'a string value');
+  t.equal(bindings.r(), 'default');
 });
diff --git a/test/js/settemplate-test.js b/test/js/settemplate-test.js
index b658acc..9f691f0 100644
--- a/test/js/settemplate-test.js
+++ b/test/js/settemplate-test.js
@@ -1,12 +1,58 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'settemplate' })
 	
 test('SetPrototypeTemplate', function (t) {
   t.plan(4);
-  var r = new bindings('settemplate').MyObject();
+  var r = new bindings.MyObject();
   t.type(r, 'object');
   r = Object.getPrototypeOf(r);
   t.type(r, 'object');
-  t.type(r.test, 'string');
-  t.equal(r.test, 'a prototype property');
+  t.type(r.prototypeProp, 'string');
+  t.equal(r.prototypeProp, 'a prototype property');
+});
+
+test('SetInstanceTemplate', function (t) {
+  t.plan(3);
+  var r = new bindings.MyObject();
+  t.type(r, 'object');
+  t.type(r.instanceProp, 'string');
+  t.equal(r.instanceProp, 'an instance property');
+});
+
+test('PropertyAttribute None', function (t) {
+  t.plan(3);
+  var r = new bindings.MyObject();
+  t.type(r, 'object');
+  t.type(r.none, 'string');
+  t.equal(r.none, 'none');
+});
+
+test('PropertyAttribute ReadOnly', function (t) {
+  t.plan(4);
+  var r = new bindings.MyObject();
+  t.type(r, 'object');
+  t.type(r.readOnly, 'string');
+  t.equal(r.readOnly, 'readOnly');
+  r.readOnly = 'changed';
+  t.equal(r.readOnly, 'readOnly');
+});
+
+test('PropertyAttribute DontEnum', function (t) {
+  t.plan(4);
+  var r = new bindings.MyObject();
+  t.type(r, 'object');
+  t.type(r.dontEnum, 'string');
+  t.equal(r.dontEnum, 'dontEnum');
+  t.notOk(r.propertyIsEnumerable('dontEnum'), 'is not enumerable');
+});
+
+test('PropertyAttribute DontDelete', function (t) {
+  t.plan(4);
+  var r = new bindings.MyObject();
+  t.type(r, 'object');
+  t.type(r.dontDelete, 'string');
+  t.equal(r.dontDelete, 'dontDelete');
+  delete r.dontDelete;
+  t.equal(r.dontDelete, 'dontDelete');
 });
diff --git a/test/js/settergetter-test.js b/test/js/settergetter-test.js
index b09e466..953bcdf 100644
--- a/test/js/settergetter-test.js
+++ b/test/js/settergetter-test.js
@@ -1,9 +1,10 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'settergetter' });
 
 test('settergetter', function (t) {
   t.plan(4)
-  var settergetter = bindings('settergetter').create()
+  var settergetter = bindings.create()
   t.equal(settergetter.prop1, 'this is property 1')
   t.ok(settergetter.prop2 === '')
   settergetter.prop2 = 'setting a value'
diff --git a/test/js/strings-test.js b/test/js/strings-test.js
index c380923..76acba1 100644
--- a/test/js/strings-test.js
+++ b/test/js/strings-test.js
@@ -1,68 +1,23 @@
 const test     = require('tap').test
-    , bindings = require('bindings')
-    , crypto   = require('crypto')
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'strings' });
 
-const ASCII  = 0
-    , UTF8   = 1
-    , BASE64 = 2
-    , UCS2   = 3
-    , BINARY = 4
-    , HEX    = 5
-    , BUFFER = 6
 
 test('FromV8String', function (t) {
-  t.plan(17)
-
-  var r = bindings('strings').returnString
-
-  t.type(r, 'function')
-  t.equal(r('an ascii string', ASCII), 'an ascii string')
-  t.equal(r('an utf8 strïng', UTF8), 'an utf8 strïng')
-  t.equal(r('YSBiYXNlNjQgc3RyaW5n', BASE64), 'a base64 string')
-  t.equal(r('an ucs2 strïng', UCS2), 'an ucs2 strïng')
-  t.equal(r('a binary string', BINARY), 'a binary string')
-  t.equal(r('612068657820737472696E67', HEX), 'a hex string')
-  t.equal(r('a buffer string', BUFFER), 'a buffer string')
-  t.equal(r(new Buffer('an actual buffer'), BUFFER), 'an actual buffer')
-  t.equal(r('an ascii string', ASCII, 1), 'an ascii string')
-  t.equal(r('an utf8 strïng', UTF8, 1), 'an utf8 strïng')
-  t.equal(r('YSBiYXNlNjQgc3RyaW5n', BASE64, 1), 'a base64 string')
-  t.equal(r('an ucs2 strïng', UCS2, 1), 'an ucs2 strïng')
-  t.equal(r('a binary string', BINARY, 1), 'a binary string')
-  t.equal(r('612068657820737472696E67', HEX, 1), 'a hex string')
-  t.equal(r('a buffer string', BUFFER, 1), 'a buffer string')
-  t.equal(r(new Buffer('an actual buffer'), BUFFER, 1), 'an actual buffer')
-})
-
-test('return NanCString', function (t) {
-  t.plan(2);
-  var r = bindings('strings').returnCString
-  t.type(r, 'function');
-  t.equal(r('an utf8 strïng'), 'an utf8 strïng');
+  t.plan(8);
+
+  var a = bindings.returnAsciiString;
+  var b = bindings.returnUtf8String;
+  var c = bindings.returnUcs2String;
+  var d = bindings.heapString;
+
+  t.type(a, 'function');
+  t.type(b, 'function');
+  t.type(c, 'function');
+  t.type(d, 'function');
+
+  t.equal(a('an ascii string'), 'an ascii string');
+  t.equal(b('an utf8 strïng'), 'an utf8 strïng');
+  t.equal(c('an ucs2 strïng'), 'an ucs2 strïng');
+  t.equal(d('an utf8 strïng'), 'an utf8 strïng');
 });
-
-test('compare NanCString', function (t) {
-  var compareCStringToBuffer = bindings('strings').compareCStringToBuffer
-  t.type(compareCStringToBuffer, 'function')
-
-  try {
-    t.ok(compareCStringToBuffer('this is a standard c string', new Buffer('this is a standard c string')))
-  } catch (e) {
-    t.fail(e)
-  }
-  t.end()
-})
-
-test('compare NanRawString', function (t) {
-  var compareRawStringToBuffer = bindings('strings').compareRawStringToBuffer
-    , rndStr                   = crypto.randomBytes(32)
-
-  t.type(compareRawStringToBuffer, 'function')
-
-  try {
-    t.ok(compareRawStringToBuffer(rndStr.toString('base64'), rndStr))
-  } catch (e) {
-    t.fail(e)
-  }
-  t.end()
-})
diff --git a/test/js/symbols-test.js b/test/js/symbols-test.js
index 9559324..eaf3eb6 100644
--- a/test/js/symbols-test.js
+++ b/test/js/symbols-test.js
@@ -1,8 +1,9 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'symbols' });
 
 test('symbols', function (t) {
   t.plan(2);
-  t.type(bindings('symbols').key, 'string');
-  t.equal(bindings('symbols').key, 'a property');
+  t.type(bindings.key, 'string');
+  t.equal(bindings.key, 'a property');
 });
diff --git a/test/js/weak-test.js b/test/js/weak-test.js
index 829d769..4c0badc 100644
--- a/test/js/weak-test.js
+++ b/test/js/weak-test.js
@@ -1,10 +1,11 @@
 const test     = require('tap').test
-    , bindings = require('bindings');
+    , testRoot = require('path').resolve(__dirname, '..')
+    , bindings = require('bindings')({ module_root: testRoot, bindings: 'weak' });
 
 test('weak', function (t) {
   t.plan(3);
 
-  var weak = bindings('weak');
+  var weak = bindings;
   t.type(weak.hustle, 'function');
 
   function f() {
diff --git a/test/package.json b/test/package.json
deleted file mode 100644
index 33efd11..0000000
--- a/test/package.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "nan-tests",
-  "version": "0.0.0",
-  "description": "",
-  "private": true,
-  "gypfile": true,
-  "scripts": {
-    "test": "node-gyp rebuild && tap --gc js/*-test.js"
-  },
-  "dependencies": {
-    "tap": "~0.4.3",
-    "bindings": "~1.1.1",
-    "xtend": "~2.1.1",
-    "node-gyp": "~0.12.1"
-  }
-}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-nan.git



More information about the Pkg-javascript-commits mailing list