var assert = require('assert'); var ref = require('ref'); var ffi = require('../'); var voidPtr = ref.refType(ref.types.void); // these are "opaque" pointer types, so we only care about the memory addess, // and not the contents (which are internal to Apple). Therefore we can typedef // these opaque types to `void *` and it's essentially the same thing. var id = voidPtr; var SEL = voidPtr; var Class = voidPtr; if (ffi.HAS_OBJC) { describe('@try / @catch', function () { // not entirely sure why this works, but we have to load `Foundation` first, // otherwise Objective-C exceptions will not work. Magic! // https://github.com/node-ffi/node-ffi/issues/195 var lib = ffi.DynamicLibrary('/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation') afterEach(gc); var objcLib = new ffi.Library('libobjc', { 'objc_msgSend': [ id, [ id, SEL ] ], 'objc_getClass': [ Class, [ 'string' ] ], 'sel_registerName': [ SEL, [ 'string' ] ] }); // create an NSAutoreleasePool instance var NSAutoreleasePool = objcLib.objc_getClass('NSAutoreleasePool'); var sel_new = objcLib.sel_registerName('new'); var pool = objcLib.objc_msgSend(NSAutoreleasePool, sel_new); it('should proxy @try/@catch to JavaScript via try/catch/throw', function () { var sel_retain = objcLib.sel_registerName('retain'); assert.throws(function () { objcLib.objc_msgSend(pool, sel_retain); }); }); it('should throw a Buffer instance when an exception happens', function () { var sel_retain = objcLib.sel_registerName('retain'); assert.throws(function () { objcLib.objc_msgSend(pool, sel_retain); }, function (e) { return Buffer.isBuffer(e) && !e.isNull() && e.address() > 0; }); }); }); }