import { nodeify } from '../../';
import Promise from '../util/promise';
import test from 'ava';

test.cb('nodeify(fn)', (t) => {
    t.plan(2);

    function unicorn(cb) {
        return Promise.resolve(1)
        .then(nodeify(cb), nodeify(cb));
    }

    unicorn((err, value) => {
        t.is(value, 1);
        t.notOk(err);

        t.end();
    });
});

test.cb('nodeify(fn): deal with promise failure', (t) => {
    t.plan(2);

    function unicorn(cb) {
        return Promise.reject(new Error('Failed promise'))
        .then(nodeify(cb), nodeify(cb));
    }

    unicorn((err, value) => {
        t.is(err.message, 'Failed promise');
        t.notOk(value);

        t.end();
    });
});

test.skip.cb('nodeify(fn): deal with fn throwing when called on failure', (t) => {
    // process.once('uncaughtException', (err) => {
    //     t.is(err.message, 'Failed promise');
    //     t.end();
    // });

    // TODO: Propose this method to AVA
    t.throwsUncaughtException('Failed promise');

    Promise.resolve('unicorn')
    .then(nodeify((err, value) => {
        t.is(value, 'unicorn');
        t.notOk(err);

        throw new Error('Failed promise');
    }), null);
});

test.skip.cb('nodeify(fn): deal with fn throwing when called with success', (t) => {
    // process.once('uncaughtException', (err) => {
    //     t.is(err.message, 'Failed promise');
    //     t.end();
    // });

    // TODO: Propose this method to AVA
    t.throwsUncaughtException('Failed promise');

    Promise.reject(new Error('Failed promise'))
    .then(null, nodeify((err, value) => {
        t.is(err.message, 'Failed promise');
        t.notOk(value);

        throw err;
    }));
});

test('nodeify()', (t) => {
    return Promise.resolve(1)
    .then(nodeify())
    .then((value) => {
        t.is(value, 1);
    });
});

test('nodeify(): deal with failure', (t) => {
    return t.throws(
        Promise.reject(new Error('Bad unicorn'))
        .then(nodeify(), nodeify()),
        'Bad unicorn'
    );
});

@@ -698,97 +698,322 @@
 );%0A%0A
-test.skip.cb('nodeify(fn): deal with fn throwing when called on failure', (t) =%3E %7B
+// TODO: Propose this method to AVA%0Afunction throwsUncaughtException(fn) %7B%0A    const listeners = process.listeners('uncaughtException');%0A    const avaListener = listeners%5Blisteners.length - 1%5D;%0A%0A    // Remove AVA listener & track uncaught exception%0A    process.removeListener('uncaughtException', avaListener);
 %0A   
- //
  pro
@@ -1062,56 +1062,133 @@
     
-//
     
- t.is(err.message, 'Failed promise
+// Restore listeners exactly how they were, including order%0A        process.removeAllListeners('uncaughtException
 ');%0A    
 //  
@@ -1187,82 +1187,199 @@
     
-//
     
- t.end(
+listeners.forEach((listener) =%3E process.on('uncaughtException', listener)
 );%0A
+%0A
     
-// %7D
+    fn(err
 );%0A
-%0A
     
-// TODO: Propose this method to AVA
+%7D);%0A%7D%0A%0Atest.cb('nodeify(fn): deal with fn throwing when called on failure', (t) =%3E %7B
 %0A    
-t.
 thro
@@ -1398,32 +1398,94 @@
 ception(
-'Failed promise'
+(err) =%3E %7B%0A        t.is(err.message, 'Failed promise');%0A        t.end();%0A    %7D
 );%0A%0A    
@@ -1674,13 +1674,8 @@
 est.
-skip.
 cb('
@@ -1753,26 +1753,15 @@
     
-// process.once('u
+throwsU
 ncau
@@ -1764,35 +1764,33 @@
 ncaughtException
-', 
+(
 (err) =%3E %7B%0A    /
@@ -1788,23 +1788,20 @@
 %3E %7B%0A    
-//
     
- 
 t.is(err
@@ -1832,19 +1832,16 @@
 e');%0A   
- //
      t.e
@@ -1854,102 +1854,9 @@
     
-// %7D);%0A%0A    // TODO: Propose this method to AVA%0A    t.throwsUncaughtException('Failed promise'
+%7D
 );%0A%0A

Update nodeify tests with custom uncaughtException validator