<commit_before>/*
** Module dependencies
*/
var mongoose = require('../config/mongoose').instance();
var _ = require('lodash');
var async = require('async');
var apiOptions = require('../config/options');

var DroitSchema = require('./schemas/droit');

var AcceptanceTestSchema = new mongoose.Schema({
    name: { type: String },
    description: { type: String },
    keywords: { type: [String] },

    priority: { type: String, enum: ['low', 'normal', 'high'], required: true, default: 'normal' },
    state: { type: String, enum: ['validated', 'pending', 'rejected', 'unclaimed'], required: true, default: 'pending' },
    rejectionMessage: { type: String },

    user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },

    scenario: { type: mongoose.Schema.Types.Mixed, required: true },

    expectedResults: [DroitSchema],
    currentStatus: { type: String, enum: ['accepted-exact', 'accepted-2pct', 'accepted-10pct', 'rejected'] },
    lastExecution: { type: mongoose.Schema.Types.ObjectId, ref: 'AcceptanceTestExecution' },

    _created: { type: Date },
    _updated: { type: Date }

});

AcceptanceTestSchema.pre('save', function (next) {
    var now = Date.now();

    if (this.isNew) {
        this._created = now;
    }

    this._updated = now;

    next();
});

AcceptanceTestSchema.methods = {

    simulate: function(done) {
        apiOptions.simulate(this, done);
    },

    execute: function(done) {
        var AcceptanceTestExecution = mongoose.model('AcceptanceTestExecution');
        var acceptanceTest = this;

        var indexExpectedResults = _.indexBy(acceptanceTest.expectedResults, 'code');

        function buildDroit(code, result) {
            var droitSimule = { code: code, result: result };
            var droitAttendu = indexExpectedResults[code];

            if (droitAttendu) {
                droitSimule.expectedValue = droitAttendu.expectedValue;

                var percentDiff;

                if (typeof result === 'number' && droitAttendu.expectedValue !== 0) {
                    percentDiff = Math.abs((droitAttendu.expectedValue - result) / droitAttendu.expectedValue);
                } else if ((typeof result === 'number' && droitAttendu.expectedValue === 0) || typeof result === 'boolean') {
                    percentDiff = droitAttendu.expectedValue === result ? 0 : 1;
                }

                droitSimule.percentDiff = percentDiff;

                if (percentDiff === 0) {
                    droitSimule.status = 'accepted-exact';
                }
                if (percentDiff > 0 && percentDiff <= 0.02) {
                    droitSimule.status = 'accepted-2pct';
                }
                if (percentDiff > 0.02 && percentDiff <= 0.1) {
                    droitSimule.status = 'accepted-10pct';
                }
                if (percentDiff > 0.1) {
                    droitSimule.status = 'rejected';
                }
            }

            return droitSimule;
        }

        apiOptions.simulate(acceptanceTest, function (err, results) {
            if (err) return done(err);

            var statusList = {
                'accepted-exact': 1,
                'accepted-2pct': 2,
                'accepted-10pct': 3,
                'rejected': 4
            };

            var testStatus = 'accepted-exact';
            var previousStatus = acceptanceTest.currentStatus;

            var evaluatedResults = _.map(results, function(value, code) {
                var droit = buildDroit(code, value);

                if (!droit.status && !droit.result) return;

                if (droit.status && (statusList[droit.status] > statusList[testStatus])) {
                    testStatus = droit.status;
                }

                return droit;
            });

            evaluatedResults = _.compact(evaluatedResults);

            var execution = new AcceptanceTestExecution();

            async.series([

                function saveExecution(cb) {
                    execution
                        .set('acceptanceTest', acceptanceTest._id)
                        .set('results', evaluatedResults)
                        .set('status', testStatus)
                        .set('date', Date.now())
                        .save(cb);
                },

                function saveTest(cb) {
                    acceptanceTest
                        .set('lastExecution', execution._id)
                        .set('currentStatus', testStatus)
                        .save(cb);
                },

                function createActivity(cb) {
                    if (testStatus === previousStatus) return cb();

                    acceptanceTest.createActivity({
                        type: 'results_update',
                        date: Date.now(),
                        content: {
                            execution: execution._id,
                            status: testStatus
                        }
                    }, cb);
                }

            ], function (err) {<commit_msg>Add resultUpdated property to AcceptanceTest<commit_after>/*
** Module dependencies
*/
var mongoose = require('../config/mongoose').instance();
var _ = require('lodash');
var async = require('async');
var apiOptions = require('../config/options');

var DroitSchema = require('./schemas/droit');

var AcceptanceTestSchema = new mongoose.Schema({
    name: { type: String },
    description: { type: String },
    keywords: { type: [String] },

    priority: { type: String, enum: ['low', 'normal', 'high'], required: true, default: 'normal' },
    state: { type: String, enum: ['validated', 'pending', 'rejected', 'unclaimed'], required: true, default: 'pending' },
    rejectionMessage: { type: String },

    user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },

    scenario: { type: mongoose.Schema.Types.Mixed, required: true },

    expectedResults: [DroitSchema],
    currentStatus: { type: String, enum: ['accepted-exact', 'accepted-2pct', 'accepted-10pct', 'rejected'] },
    lastExecution: { type: mongoose.Schema.Types.ObjectId, ref: 'AcceptanceTestExecution' },
    resultUpdated: {type: Date},

    _created: { type: Date },
    _updated: { type: Date }

});

AcceptanceTestSchema.pre('save', function (next) {
    var now = Date.now();

    if (this.isNew) {
        this._created = now;
    }

    this._updated = now;

    next();
});

AcceptanceTestSchema.methods = {

    simulate: function(done) {
        apiOptions.simulate(this, done);
    },

    execute: function(done) {
        var AcceptanceTestExecution = mongoose.model('AcceptanceTestExecution');
        var acceptanceTest = this;

        var indexExpectedResults = _.indexBy(acceptanceTest.expectedResults, 'code');

        function buildDroit(code, result) {
            var droitSimule = { code: code, result: result };
            var droitAttendu = indexExpectedResults[code];

            if (droitAttendu) {
                droitSimule.expectedValue = droitAttendu.expectedValue;

                var percentDiff;

                if (typeof result === 'number' && droitAttendu.expectedValue !== 0) {
                    percentDiff = Math.abs((droitAttendu.expectedValue - result) / droitAttendu.expectedValue);
                } else if ((typeof result === 'number' && droitAttendu.expectedValue === 0) || typeof result === 'boolean') {
                    percentDiff = droitAttendu.expectedValue === result ? 0 : 1;
                }

                droitSimule.percentDiff = percentDiff;

                if (percentDiff === 0) {
                    droitSimule.status = 'accepted-exact';
                }
                if (percentDiff > 0 && percentDiff <= 0.02) {
                    droitSimule.status = 'accepted-2pct';
                }
                if (percentDiff > 0.02 && percentDiff <= 0.1) {
                    droitSimule.status = 'accepted-10pct';
                }
                if (percentDiff > 0.1) {
                    droitSimule.status = 'rejected';
                }
            }

            return droitSimule;
        }

        apiOptions.simulate(acceptanceTest, function (err, results) {
            if (err) return done(err);

            var statusList = {
                'accepted-exact': 1,
                'accepted-2pct': 2,
                'accepted-10pct': 3,
                'rejected': 4
            };

            var testStatus = 'accepted-exact';
            var previousStatus = acceptanceTest.currentStatus;

            var evaluatedResults = _.map(results, function(value, code) {
                var droit = buildDroit(code, value);

                if (!droit.status && !droit.result) return;

                if (droit.status && (statusList[droit.status] > statusList[testStatus])) {
                    testStatus = droit.status;
                }

                return droit;
            });

            evaluatedResults = _.compact(evaluatedResults);

            var execution = new AcceptanceTestExecution();

            async.series([

                function saveExecution(cb) {
                    execution
                        .set('acceptanceTest', acceptanceTest._id)
                        .set('results', evaluatedResults)
                        .set('status', testStatus)
                        .set('date', Date.now())
                        .save(cb);
                },


                function createActivity(cb) {
                    if (testStatus === previousStatus) return cb();
                    var now = Date.now();
                    acceptanceTest.set('resultUpdated', now);

                    acceptanceTest.createActivity({
                        type: 'results_update',
                        date: now,
                        content: {
                            execution: execution._id,
                            status: testStatus
                        }
                    }, cb);
                },

                function saveTest(cb) {
                    acceptanceTest
                        .set('lastExecution', execution._id)
                        .set('currentStatus', testStatus)
                        .save(cb);
                },
            ], function (err) {
{'fraction_non_alphanumeric': 0.12005071191730056, 'fraction_numerical': 0.005656329237370782, 'mean_word_length': 1.6301615798922802, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, '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': '3193561', 'n_tokens_mistral': 2759, 'n_tokens_neox': 2587, 'n_words': 572}