<commit_before>#!/usr/bin/env node

//require('child_process').spawn = mockChild;
function mockChild(command, args) {
    var action = (args.indexOf('-l') >= 0) ? 'load' : 'save',
        user   = '',
        uRegEx = /-u\s([^\s]+)/;
    
    for (var i = 0; i < args.length; i++) {
        var arg    = args[i],
            tokens = arg.match(uRegEx);
        
        user = tokens && tokens[1] || '';
        
        if (user) { break; }
    };
    
    function load(child) {
        process.nextTick(function() {
            if (mockChild.isRoot == false && user != '') {
                child.stderr.emit('data', 'crontab: must be privileged to use -u');
                child.emit('exit', '1');
            }
            else if (mockChild.hasTabs == false) {
                child.stderr.emit('data', 'crontab: no crontab for ...');
                child.emit('exit', '1');
            }
            else {
                child.stdout.emit('data', mockChild.tabs);
                child.emit('exit', '0');
            }
        });
    }
    
    function save(child, tabs) {
        process.nextTick(function() {
            if (mockChild.isRoot == false && user != '') {
                child.stderr.emit('data', 'crontab: must be privileged to use -u');
                child.emit('exit', '1');
            }
            else {
                mockChild.tabs = tabs;
                child.emit('exit', '0');
            }
        });
    }
    
    var child = new process.EventEmitter;
    child.stdout = new process.EventEmitter;
    child.stderr = new process.EventEmitter;
    child.stdin  = {
        buffer : '',
        write  : function(tabs) { this.buffer = tabs; },
        end    : function(tabs) { save(child, this.buffer); }
    }
    
    if (action == 'load') {
        load(child);
    }
    
    return child;
}
mockChild.isRoot  = false;
mockChild.hasTabs = false;
mockChild.tabs    = '';


var Vows    = require('vows'),
    Assert  = require('assert'),
    CronTab = require('../lib/index');

Vows.describe('crontab').addBatch({
    'io': {
        topic: loadTabs,
        'will load user tabs':function(err, tab) {
            Assert.isNull(err);
            Assert.isObject(tab);
        },
        'after tabs are loaded': {
            topic:saveTabs,
            'will save user tabs':function(err, tab) {
                Assert.isNull(err);
                Assert.isObject(tab);
            },
            'then saved': {
                topic: loadTabs,
                'will load user tabs again':function(err, tab) {
                    Assert.isNull(err);
                    Assert.isObject(tab);
                },
                'and then loaded again': {
                    topic: makeTabArrayFromTopicStack,
                    'they will be the same':function(tabs) {
                        Assert.equal(tabs[0].render(), tabs[1].render());
                    }
                }
            }
        }
    }
}).export(module);

function loadTabs() {
    var promise = new(process.EventEmitter);
    
    CronTab.load('', function(err, tab) {
        if (err) { promise.emit('error', err); }
        else     { promise.emit('success', tab); }
    });
    
    return promise;
}

function saveTabs(tab) {
    var promise = new(process.EventEmitter);
    
    tab.save(function(err, tab) {
        if (err) { promise.emit('error', err); }
        else     { promise.emit('success', tab); }
    });
    
    return promise;
}

function makeTabArrayFromTopicStack() {
    var tab1 = arguments[0],
        tab2 = arguments[2];
    
    return [tab1, tab2];
}<commit_msg>Created new load/save unit tests using a mock child process<commit_after>#!/usr/bin/env node

require('child_process').spawn = mockChild;

// Mock child_process
function mockChild(command, args) {
    var undefined,
        action = (args.indexOf('-l') >= 0) ? 'load' : 'save',
        user   = '',
        uRegEx = /-u\s([^\s]+)/;
    
    for (var i = 0; i < args.length; i++) {
        var arg    = args[i],
            tokens = arg.match(uRegEx);
        
        user = tokens && tokens[1] || '';
        
        if (user) { break; }
    };
    
    function load(child) {
        process.nextTick(function() {
            if (mockChild.user != 'root' && user != '') {
                child.stderr.emit('data', 'crontab: must be privileged to use -u');
                child.emit('exit', '1');
                return;
            }
            
            var tabs = mockChild.tabs[user || mockChild.user];
            if (tabs == undefined && user != '') {
                child.stderr.emit('data', 'crontab: user ' + user + ' unknown');
                child.emit('exit', '1');
                return;
            }
            if (tabs == null) {
                child.stderr.emit('data', 'crontab: no crontab for ...');
                child.emit('exit', '1');
                return;
            }
            
            child.stdout.emit('data', tabs);
            child.emit('exit', '0');
        });
    }
    
    function save(child, newTabs) {
        process.nextTick(function() {
            if (mockChild.user != 'root' && user != '') {
                child.stderr.emit('data', 'crontab: must be privileged to use -u');
                child.emit('exit', '1');
            }
            else {
                mockChild.tabs[user || mockChild.user] = newTabs;
                child.emit('exit', '0');
            }
        });
    }
    
    var child = new process.EventEmitter;
    child.stdout = new process.EventEmitter;
    child.stderr = new process.EventEmitter;
    child.stdin  = {
        buffer : '',
        write  : function(tabs) { this.buffer = tabs; },
        end    : function(tabs) { save(child, this.buffer); }
    }
    
    if (action == 'load') {
        load(child);
    }
    
    return child;
}
mockChild.user = 'blago';
mockChild.tabs = {
    alice : '0 8-17 * * 1-5 /usr/bin/env echo "check email"\n\
            * 19-0,0-3 * * 1-5 /usr/bin/env echo "hack node.js"\n\
            30 11 * * 6-0 /usr/bin/env echo "wake up"\n\
            * * * 5-8 * /usr/bin/env echo "go to Bulgaria"\n\
            30 9 24 dec * /usr/bin/env echo "get presents"\n\
            @reboot /usr/bin/env echo "starting some service..."\n',
    bob   : '0 8-17 * * 1-5 /usr/bin/env echo "check email"\n\
            * 19-0,0-3 * * 1-5 /usr/bin/env echo "hack node.js"\n\
            30 11 * * 6-0 /usr/bin/env echo "wake up"\n',
    blago : null,
    root  : ''
};


// Test helpers
function loadTabs(user) {
    var promise = new(process.EventEmitter);
    
    CronTab.load(user, function(err, tab) {
        if (err) { promise.emit('error', err); }
        else     { promise.emit('success', tab); }
    });
    
    return promise;
}
function saveTabs(tab) {
    var promise = new(process.EventEmitter);
    
    tab.save(function(err, tab) {
        if (err) { promise.emit('error', err); }
        else     { promise.emit('success', tab); }
    });
    
    return promise;
}
function makeTabArrayFromTopicStack() {
    var tab1 = arguments[0],
        tab2 = arguments[2];
    
    return [tab1, tab2];
}


// Test batches
var nonRootLoadsAnoterUserCrons = {
    'non-root user loads another user\'s crons': {
        topic: function() {
            mockChild.user = 'blago';
            return loadTabs('alice');
        },
        'should fail':function(err, tab) {
            Assert.isObject(err);
            Assert.isString(err.message);
            Assert.matches(err.message, /privileged/);
        }
    }
};
var rootLoadsAnoterUserCrons = {
    'root user loads another (existing) user\'s crons': {
        topic: function() {
            mockChild.user = 'root';
            return loadTabs('bob');
        },
        'should succeed':function(err, tab) {
            rootLoadsAnoterUserCrons.tab = tab;
            
            Assert.isNull(err);
            Assert.isObject(tab);
            Assert.isArray(tab.getJobs());
            Assert.equal(tab.getJobs().length, 3);
        }
    }
};
var rootLoadsAnoterNonExistingUserCrons = {
    'root user loads another (non-existing) user\'s crons': {
        topic: function() {
            mockChild.user = 'root';
            return loadTabs('tom');
        },
        'should fail':function(err, tab) {
            Assert.isObject(err);
            Assert.isString(err.message);
            Assert.matches(err.message, /unknown/);
        }
    }
};
var userLoadsHisOwnEmptyCrons = {
    'user loads his own (empty) crons': {
        topic: function() {
            mockChild.user = 'blago';
            return loadTabs('');
        },
        'should succeed':function(err, tab) {
            userLoadsHisOwnEmptyCrons.tab = tab;
            
            Assert.isNull(err);
            Assert.isObject(tab);
            Assert.isArray(tab.getJobs());
            Assert.equal(tab.getJobs().length, 0);
        }
    }
};
var userLoadsHerOwnNonEmptyCrons = {
    'user loads her own (non-empty) crons': {
        topic: function() {
            mockChild.user = 'alice';
            return loadTabs('');
        },
        'should succeed':function(err, tab) {
            userLoadsHerOwnNonEmptyCrons.tab = tab;
            
            Assert.isNull(err);
            Assert.isObject(tab);
            Assert.isArray(tab.getJobs());
            Assert.equal(tab.getJobs().length, 6);
        }
    }
};
var userSavesHerOwnNonEmptyCrons = {
    'user saves her own (non-empty) crons': {
        topic: function() {
            return saveTabs(userLoadsHerOwnNonEmptyCrons.tab);
        },
        'should succeed':function(err, tab) {
            Assert.isNull(err);
            Assert.isObject(tab);
        }
    }
};
var userLoadsHerOwnNonEmptyCronsAgain = {
    'user loads her own (non-empty) crons again': {
        topic: function() {
            mockChild.user = 'alice';
            return loadTabs('');
        },
        'should succeed':function(err, tab) {
            userLoadsHerOwnNonEmptyCronsAgain.tab = tab;
            
            Assert.isNull(err);
            Assert.isObject(tab);
            Assert.isArray(tab.getJobs());
            Assert.equal(tab.getJobs().length, 6);
        },
        'are the same':function(err, thisTab) {
            var firstTab = userLoadsHerOwnNonEmptyCrons.tab;
            
            Assert.equal(firstTab.render(), thisTab.render());
        }
    }
};


var Vows    = require('vows'),
    Assert  = require('assert'),
    CronTab = require('../lib/index');

Vows.describe('crontab').
    addBatch(nonRootLoadsAnoterUserCrons).
    addBatch(rootLoadsAnoterUserCrons).
    addBatch(rootLoadsAnoterNonExistingUserCrons).
    addBatch(userLoadsHisOwnEmptyCrons).
    addBatch(userLoadsHerOwnNonEmptyCrons).
    addBatch(userSavesHerOwnNonEmptyCrons).
    addBatch(userLoadsHerOwnNonEmptyCronsAgain).
    export(module);
{'fraction_non_alphanumeric': 0.14630343056319942, 'fraction_numerical': 0.00733810310034856, 'mean_word_length': 1.6808458323088271, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '7609528', 'n_tokens_mistral': 3399, 'n_tokens_neox': 3313, 'n_words': 663}