<commit_before>require('proof')(20, require('cadence')(prove))

function prove (async, okay) {
    var Destructible = require('..')

    var destructible = new Destructible('bad')

    destructible.destruct.wait(function () { throw new Error('bad') })
    destructible.completed.wait(function (error) {
        okay(error.cause.message, 'bad','bad destructor')
    })
    destructible.destroy()

    var destructible = new Destructible('keyed')
    okay(destructible.key, 'keyed', 'keyed')
    var destructible = new Destructible
    okay(destructible.key, null, 'unkeyed')

    var object = { destroyed: false }

    destructible.markDestroyed(object, 'destroyed')

    destructible.destroy()
    okay(destructible.destroyed, 'marked destroyed')
    destructible.destroy()

    function Daemon () {
        this._callback = null
    }

    Daemon.prototype.destroy = function () {
        this._callback.call()
    }

    Daemon.prototype.listen = function (destructible, value, callback) {
        okay(value, 1, 'listening')
        this._callback = destructible.monitor('main')
        destructible.destruct.wait(this, 'destroy')
        destructible.destruct.wait(this, function () {
            okay(true, 'sub-destructible destruct one')
        })
        destructible.destruct.wait(this, function () {
            okay(true, 'sub-destructible destruct two')
        })
        var cookie = destructible.destruct.wait(function () { okay(true, 'canceled') })
        destructible.destruct.cancel(cookie)()
        callback()
    }

    async(function () {
        var destructible = new Destructible('daemons')
        var daemon = new Daemon
        async(function () {
            destructible.monitor('daemon', daemon, 'listen', 1, async())
        }, function () {
            destructible.destroy()
            destructible.completed.wait(async())
        }, [function () {
            destructible.monitor('daemon', daemon, 'listen', 1, async())
        }, function (error) {
            okay(error.qualified, 'destructible#destroyed', 'already destroyed')
        }])
    }, function () {
        destructible = new Destructible('daemons')
        async(function () {
            destructible.monitor('destroyed', function (destructible, callback) {
                setImmediate(function () { destructible.destroy() })
                callback()
            }, null)
            destructible.completed.wait(async())
        }, function () {
            okay(destructible.destroyed, 'hard fork')
        })
    }, function () {
        // We should be able to reach `okay` without having to explicitly
        // destroy the parent Destructible, the child exiting will trigger
        // `destroy` in the parent.
        destructible = new Destructible('daemons')
        async(function () {
            destructible.monitor('destroyed', function (destructible, callback) {
                setImmediate(function () { destructible.destroy() })
                callback()
            }, async())
        }, function () {
            destructible.completed.wait(async())
        }, function () {
            okay(destructible.destroyed, 'parent destroyed')
        })
    }, function () {
        // Here we're testing what happpens when we destroy immediately.
        // destroy the parent Destructible, the child exiting will trigger
        // `destroy` in the parent.
        destructible = new Destructible('daemons')
        async(function () {
            destructible.monitor('destroyed', function (destructible, callback) {
                destructible.destroy()
                callback()
            }, async())
        }, function () {
            okay(destructible.destroyed, 'parent destroyed immediately')
            destructible.completed.wait(async())
        })
    }, function () {
        destructible = new Destructible('daemons')
        destructible.completed.wait(async())
        async(function () {
            destructible.monitor('destroyed', true, function (destructible, callback) {
                destructible.destroy()
                callback()
            }, async())
        }, function () {
            okay(!destructible.destroyed, 'parent spared')
            destructible.destroy()
            destructible.completed.wait(async())
        })
    }, function () {
        var destructible = new Destructible('scrammed')
        async(function () {
            destructible.monitor('sub-scrammed', function (initializer, callback) {
                initializer.monitor('hung')
                callback()
            }, async())
        }, [function () {
            destructible.destroy()
            destructible.completed.wait(async())
        }, function (error) {
            okay(error.cause.qualified, 'destructible#hung', 'sub scram')
            destructible.scram()
        }])
    }, function () {
        var destructible = new Destructible('child')
        var child = destructible.destructible('child')
        child.destruct.wait(function () {
            okay(true, 'child called')
        })
        destructible.destroy()
    }, function () {
        destructible = new Destructible('daemons')
        async([function () {
            destructible.monitor('errored', function (destructible, callback) {
                destructible.destruct.wait(callback)<commit_msg>Test a worker child that errors.<commit_after>require('proof')(21, require('cadence')(prove))

function prove (async, okay) {
    var Destructible = require('..')

    var destructible = new Destructible('bad')

    destructible.destruct.wait(function () { throw new Error('bad') })
    destructible.completed.wait(function (error) {
        okay(error.cause.message, 'bad','bad destructor')
    })
    destructible.destroy()

    var destructible = new Destructible('keyed')
    okay(destructible.key, 'keyed', 'keyed')
    var destructible = new Destructible
    okay(destructible.key, null, 'unkeyed')

    var object = { destroyed: false }

    destructible.markDestroyed(object, 'destroyed')

    destructible.destroy()
    okay(destructible.destroyed, 'marked destroyed')
    destructible.destroy()

    function Daemon () {
        this._callback = null
    }

    Daemon.prototype.destroy = function () {
        this._callback.call()
    }

    Daemon.prototype.listen = function (destructible, value, callback) {
        okay(value, 1, 'listening')
        this._callback = destructible.monitor('main')
        destructible.destruct.wait(this, 'destroy')
        destructible.destruct.wait(this, function () {
            okay(true, 'sub-destructible destruct one')
        })
        destructible.destruct.wait(this, function () {
            okay(true, 'sub-destructible destruct two')
        })
        var cookie = destructible.destruct.wait(function () { okay(true, 'canceled') })
        destructible.destruct.cancel(cookie)()
        callback()
    }

    async(function () {
        var destructible = new Destructible('daemons')
        var daemon = new Daemon
        async(function () {
            destructible.monitor('daemon', daemon, 'listen', 1, async())
        }, function () {
            destructible.destroy()
            destructible.completed.wait(async())
        }, [function () {
            destructible.monitor('daemon', daemon, 'listen', 1, async())
        }, function (error) {
            okay(error.qualified, 'destructible#destroyed', 'already destroyed')
        }])
    }, function () {
        destructible = new Destructible('daemons')
        async(function () {
            destructible.monitor('destroyed', function (destructible, callback) {
                setImmediate(function () { destructible.destroy() })
                callback()
            }, null)
            destructible.completed.wait(async())
        }, function () {
            okay(destructible.destroyed, 'hard fork')
        })
    }, function () {
        // We should be able to reach `okay` without having to explicitly
        // destroy the parent Destructible, the child exiting will trigger
        // `destroy` in the parent.
        destructible = new Destructible('daemons')
        async(function () {
            destructible.monitor('destroyed', function (destructible, callback) {
                setImmediate(function () { destructible.destroy() })
                callback()
            }, async())
        }, function () {
            destructible.completed.wait(async())
        }, function () {
            okay(destructible.destroyed, 'parent destroyed')
        })
    }, function () {
        // Here we're testing what happpens when we destroy immediately.
        // destroy the parent Destructible, the child exiting will trigger
        // `destroy` in the parent.
        destructible = new Destructible('daemons')
        async(function () {
            destructible.monitor('destroyed', function (destructible, callback) {
                destructible.destroy()
                callback()
            }, async())
        }, function () {
            okay(destructible.destroyed, 'parent destroyed immediately')
            destructible.completed.wait(async())
        })
    }, function () {
        destructible = new Destructible('daemons')
        destructible.completed.wait(async())
        async(function () {
            destructible.monitor('destroyed', true, function (destructible, callback) {
                destructible.destroy()
                callback()
            }, async())
        }, function () {
            okay(!destructible.destroyed, 'parent spared')
            destructible.destroy()
            destructible.completed.wait(async())
        })
    }, [function () {
        destructible = new Destructible('daemons')
        destructible.completed.wait(async())
        destructible.monitor('destroyed', true, function (destructible, callback) {
            var monitor = destructible.monitor('exploded')
            setImmediate(function () { monitor(new Error('early')) })
            callback()
        }, async())
    }, function (error) {
        okay(error.causes[0].causes[0].message, 'early', 'terminates error')
    }], function () {
        var destructible = new Destructible('scrammed')
        async(function () {
            destructible.monitor('sub-scrammed', function (initializer, callback) {
                initializer.monitor('hung')
                callback()
            }, async())
        }, [function () {
            destructible.destroy()
            destructible.completed.wait(async())
        }, function (error) {
            okay(error.cause.qualified, 'destructible#hung', 'sub scram')
            destructible.scram()
        }])
    }, function () {
        var destructible = new Destructible('child')
        var child = destructible.destructible('child')
        child.destruct.wait(function () {
            okay(true, 'child called')
        })
        destructible.destroy()
    }, function () {
        destructible = new Destructible('daemons')
        async([function () {
            destructible.monitor('errored', function (destructible, callback) {
                destructible.destruct.wait(callback)
{'fraction_non_alphanumeric': 0.1277205553067622, 'fraction_numerical': 0.0010747872816838334, 'mean_word_length': 2.2421602787456445, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '767075', 'n_tokens_mistral': 2938, 'n_tokens_neox': 2817, 'n_words': 594}