<commit_before>/*
 * grunt-contrib-jasmine
 * http://gruntjs.com/
 *
 * Copyright (c) 2016 GruntJS Team
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // node api
  var fs = require('fs'),
      path = require('path');

  // npm lib
  var puppeteer = require('puppeteer'),
      chalk = require('chalk'),
      _ = require('lodash');

  // local lib
  var jasmine = require('./lib/jasmine').init(grunt);

  var junitTemplate = path.join(__dirname, '/jasmine/templates/JUnit.tmpl');

  var status = {};

  let resolveJasmine;
  const jasminePromise = new Promise((resolve) => {
    resolveJasmine = resolve;
  });

  var symbols = {
    none: {
      check: '',
      error: '',
      splat: ''
    },
    short: {
      check: '.',
      error: 'X',
      splat: '*'
    },
    full: {
      check: '✓',
      error: 'X',
      splat: '*'
    }
  };

  // With node.js on Windows: use symbols available in terminal default fonts
  // https://github.com/visionmedia/mocha/pull/641
  if (process && process.platform === 'win32') {
    symbols = {
      none: {
        check: '',
        error: '',
        splat: ''
      },
      short: {
        check: '.',
        error: '\u00D7',
        splat: '*'
      },
      full: {
        check: '\u221A',
        error: '\u00D7',
        splat: '*'
      }
    };
  }

  grunt.registerMultiTask('jasmine', 'Run Jasmine specs headlessly.', async function() {
    // Merge task-specific options with these defaults.
    var options = this.options({
      version: 'latest',
      timeout: 10000,
      styles: [],
      specs: [],
      helpers: [],
      vendor: [],
      polyfills: [],
      customBootFile: null,
      tempDir: '.grunt/grunt-contrib-jasmine',
      outfile: '_SpecRunner.html',
      host: '',
      template: path.join(__dirname, '/jasmine/templates/DefaultRunner.tmpl'),
      templateOptions: {},
      junit: {},
      ignoreEmpty: grunt.option('force') === true,
      display: 'full',
      summary: false
    });

    if (grunt.option('debug')) {
      grunt.log.debug(options);
    }

    var done = this.async();

    // The filter returned no spec files so skip headless.
    if (!(await jasmine.buildSpecrunner(this.filesSrc, options))) {
      done(false);
      return;
    }

    // If we're just building (e.g. for web), skip headless.
    if (this.flags.build) {
      done(true);
      return;
    }

    const err = await launchPuppeteer(options);
    var success = !err && status.failed === 0;

    if (err) {
      grunt.log.error(err);
    }
    if (status.failed === 0) {
      grunt.log.ok('0 failures');
    } else {
      grunt.log.error(status.failed + ' failures');
    }

    teardown(options, function() {
      done(success);
    });
  });

  async function launchPuppeteer(options) {
    var file = options.outfile;

    if (options.host) {
      if (!(/\/$/).test(options.host)) {
        options.host += '/';
      }
      file = options.host + options.outfile;
    } else {
      file = `file://${path.join(process.cwd(), file)}`;
    }

    let puppeteerLaunchSetting;
    if(options.hasOwnProperty('noSandbox') && options.noSandbox){
        puppeteerLaunchSetting = {args: ['--no-sandbox']};
        delete options.noSandbox;
    }

    const browser = await puppeteer.launch(puppeteerLaunchSetting);
    grunt.log.subhead(`Testing specs with Jasmine/${options.version} via ${await browser.version()}`);
    const page = await browser.newPage();

    try {
      await setup(options, page);
      await page.goto(file, { waitUntil: 'domcontentloaded' });

      await jasminePromise;
    } catch (error) {
      grunt.log.error('Error caught from Puppeteer');
      grunt.warn(error.stack);
    }

    await page.close();
    await browser.close();

    return;
  }

  function teardown(options, cb) {
    if (!options.keepRunner && fs.statSync(options.outfile).isFile()) {
      fs.unlinkSync(options.outfile);
    }

    if (!options.keepRunner) {
      jasmine.cleanTemp(options.tempDir, cb);
    } else {
      cb();
    }
  }

  async function setup(options, page) {
    var indentLevel = 1,
      tabstop = 2,
      thisRun = {},
      suites = {},
      currentSuite;

    status = {
      failed: 0
    };

    function indent(times) {
      return new Array(+times * tabstop).join(' ');
    }

    page.on('error', (error) => {
      // page has crashed
      grunt.log.error('Error caught from Headless Chrome. More info can be found by opening the Spec Runner in a browser.');
      grunt.log.warn(error.stack);
    });<commit_msg>moved resolveJasmine/jasminePromise function to fix scope issue<commit_after>/*
 * grunt-contrib-jasmine
 * http://gruntjs.com/
 *
 * Copyright (c) 2016 GruntJS Team
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // node api
  var fs = require('fs'),
      path = require('path');

  // npm lib
  var puppeteer = require('puppeteer'),
      chalk = require('chalk'),
      _ = require('lodash');

  // local lib
  var jasmine = require('./lib/jasmine').init(grunt);

  var junitTemplate = path.join(__dirname, '/jasmine/templates/JUnit.tmpl');

  var status = {};

  var symbols = {
    none: {
      check: '',
      error: '',
      splat: ''
    },
    short: {
      check: '.',
      error: 'X',
      splat: '*'
    },
    full: {
      check: '✓',
      error: 'X',
      splat: '*'
    }
  };

  // With node.js on Windows: use symbols available in terminal default fonts
  // https://github.com/visionmedia/mocha/pull/641
  if (process && process.platform === 'win32') {
    symbols = {
      none: {
        check: '',
        error: '',
        splat: ''
      },
      short: {
        check: '.',
        error: '\u00D7',
        splat: '*'
      },
      full: {
        check: '\u221A',
        error: '\u00D7',
        splat: '*'
      }
    };
  }

  grunt.registerMultiTask('jasmine', 'Run Jasmine specs headlessly.', async function() {
    // Merge task-specific options with these defaults.
    var options = this.options({
      version: 'latest',
      timeout: 10000,
      styles: [],
      specs: [],
      helpers: [],
      vendor: [],
      polyfills: [],
      customBootFile: null,
      tempDir: '.grunt/grunt-contrib-jasmine',
      outfile: '_SpecRunner.html',
      host: '',
      template: path.join(__dirname, '/jasmine/templates/DefaultRunner.tmpl'),
      templateOptions: {},
      junit: {},
      ignoreEmpty: grunt.option('force') === true,
      display: 'full',
      summary: false
    });

    if (grunt.option('debug')) {
      grunt.log.debug(options);
    }

    var done = this.async();

    // The filter returned no spec files so skip headless.
    if (!(await jasmine.buildSpecrunner(this.filesSrc, options))) {
      done(false);
      return;
    }

    // If we're just building (e.g. for web), skip headless.
    if (this.flags.build) {
      done(true);
      return;
    }

    const err = await launchPuppeteer(options);
    var success = !err && status.failed === 0;

    if (err) {
      grunt.log.error(err);
    }
    if (status.failed === 0) {
      grunt.log.ok('0 failures');
    } else {
      grunt.log.error(status.failed + ' failures');
    }

    teardown(options, function() {
      done(success);
    });
  });

  async function launchPuppeteer(options) {
    var file = options.outfile;

    if (options.host) {
      if (!(/\/$/).test(options.host)) {
        options.host += '/';
      }
      file = options.host + options.outfile;
    } else {
      file = `file://${path.join(process.cwd(), file)}`;
    }

    let puppeteerLaunchSetting;
    if(options.hasOwnProperty('noSandbox') && options.noSandbox){
        puppeteerLaunchSetting = {args: ['--no-sandbox']};
        delete options.noSandbox;
    }

    const browser = await puppeteer.launch(puppeteerLaunchSetting);
    grunt.log.subhead(`Testing specs with Jasmine/${options.version} via ${await browser.version()}`);
    const page = await browser.newPage();


    let resolveJasmine;
    const jasminePromise = new Promise((resolve) => {
      resolveJasmine = resolve;
    });

    try {
      await setup(options, page, resolveJasmine);
      await page.goto(file, { waitUntil: 'domcontentloaded' });

      await jasminePromise;
    } catch (error) {
      grunt.log.error('Error caught from Puppeteer');
      grunt.warn(error.stack);
    }

    await page.close();
    await browser.close();

    return;
  }

  function teardown(options, cb) {
    if (!options.keepRunner && fs.statSync(options.outfile).isFile()) {
      fs.unlinkSync(options.outfile);
    }

    if (!options.keepRunner) {
      jasmine.cleanTemp(options.tempDir, cb);
    } else {
      cb();
    }
  }

  async function setup(options, page, resolveJasmine) {
    var indentLevel = 1,
      tabstop = 2,
      thisRun = {},
      suites = {},
      currentSuite;

    status = {
      failed: 0
    };

    function indent(times) {
      return new Array(+times * tabstop).join(' ');
    }

    page.on('error', (error) => {
      // page has crashed
      grunt.log.error('Error caught from Headless Chrome. More info can be found by opening the Spec Runner in a browser.');
      grunt.log.warn(error.stack);
    });
{'fraction_non_alphanumeric': 0.1567252723546543, 'fraction_numerical': 0.006256067306655161, 'mean_word_length': 2.243091990206366, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 2, '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': '7414349', 'n_tokens_mistral': 3093, 'n_tokens_neox': 2945, 'n_words': 654}