codenautas/qa-control

View on GitHub
bin/0.1.4/definition.js

Summary

Maintainability
F
1 mo
Test Coverage
"use strict";

var stripBom = require("strip-bom-string");
var semver = require("semver");
var jsh = require('jshint');
var esl = require('eslint');
var multilang = require('multilang');
var fs = require('fs-promise');
var Path = require('path');

module.exports = function(qaControl){
    return {
        fileNameMainDoc: 'LEEME.md',
        sections: { // podria llamarse 'json-sections'...
            'run-in': {
                mandatory: true,
                values: {
                    server:{},
                    both:{},
                    client:{}
                }
            },
            type: {
                mandatory:true,
                values: {
                    app: {},
                    lib: {},
                    "cmd-tool": {}
                }
            }
        },
        files:{
            'README.md':{ mandatory:true },
            'LEEME.md':{ mandatory:true },
            '.travis.yml':{ mandatory:true },
            '.gitignore':{
                mandatory:true,
                mandatoryLines:['local-*','*-local.*']
            },
            'LICENSE':{ mandatory:true },
            'appveyor.yml':{
                presentIf:function(packageJson){
                    return !!packageJson['qa-control']["test-appveyor"];
                }
            }
        },
        cucardas:{
            'proof-of-concept':{
                check: function(packageJson){ 
                    return packageJson['qa-control'].purpose==='proof-of-concept';
                },
                md:'![proof-of-concept](https://img.shields.io/badge/stability-proof_of_concept-ff70c0.svg)',
                imgExample:'https://img.shields.io/badge/stability-designing-red.svg'
            },
            designing:{
                check: function(packageJson){ 
                    return semver.satisfies(packageJson.version,'0.0.x') && !packageJson['qa-control'].purpose;
                },
                md:'![designing](https://img.shields.io/badge/stability-designing-red.svg)',
                imgExample:'https://img.shields.io/badge/stability-designing-red.svg',
                docDescription: 'opt. manual'
            },
            extending:{
                check: function(packageJson){ 
                    return semver.satisfies(packageJson.version,'0.x.x') &&
                            !semver.satisfies(packageJson.version,'0.0.x') &&
                            !packageJson['qa-control'].purpose;
                },
                md:'![extending](https://img.shields.io/badge/stability-extending-orange.svg)',
                imgExample:'https://img.shields.io/badge/stability-extending-orange.svg',
                docDescription: 'opt. manual'
            },
            training:{
                check: function(packageJson){ 
                    return packageJson['qa-control'].purpose==='training';
                },
                md:'![training](https://img.shields.io/badge/stability-training-ffa0c0.svg)',
                imgExample:'https://img.shields.io/badge/stability-training-ffa0c0.svg'
            },
            example:{
                check: function(packageJson){ 
                    return packageJson['qa-control'].purpose==='example';
                },
                md:'![example](https://img.shields.io/badge/stability-example-a0a0f0.svg)',
                imgExample:'https://img.shields.io/badge/stability-example-a0a0f0.svg'
            },
            stable:{
                check: function(packageJson){ 
                    return semver.satisfies(packageJson.version,'>=1.0.0') && !packageJson['qa-control'].purpose;
                },
                md:'![stable](https://img.shields.io/badge/stability-stable-brightgreen.svg)',
                imgExample:'https://img.shields.io/badge/stability-stable-brightgreen.svg'
            },
            'npm-version':{
                mandatory:true,
                md:'[![npm-version](https://img.shields.io/npm/v/yyy.svg)](https://npmjs.org/package/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/npm-version.png',
                docDescription: ''
            },
            downloads:{
                mandatory:true,
                md:'[![downloads](https://img.shields.io/npm/dm/yyy.svg)](https://npmjs.org/package/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/downloads.png',
                docDescription: ''
            },
            build:{
                check: function(packageJson){ 
                    return !packageJson['qa-control']['test-appveyor'];
                },
                md:'[![build](https://img.shields.io/travis/xxx/yyy/master.svg)](https://travis-ci.org/xxx/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/medalla-ejemplo-linux.png',
                docDescription: 'linux/build'
            },
            linux:{
                check: function(packageJson){ 
                    return !!packageJson['qa-control']['test-appveyor'];
                },
                md:'[![linux](https://img.shields.io/travis/xxx/yyy/master.svg)](https://travis-ci.org/xxx/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/medalla-ejemplo-linux.png',
                hideInManual: true,
            },
            windows:{
                check: function(packageJson){ 
                    return !!packageJson['qa-control']['test-appveyor'];
                },
                md:'[![windows](https://ci.appveyor.com/api/projects/status/github/xxx/yyy?svg=true)](https://ci.appveyor.com/project/xxx/yyy)',
                imgExample:'https://ci.appveyor.com/api/projects/status/github/codenautas/pg-promise-strict?svg=true',
                docDescription: 'casos especiales'
            },
            coverage:{
                check: function(packageJson){ 
                    return packageJson['qa-control'].coverage;
                },
                md:'[![coverage](https://img.shields.io/coveralls/xxx/yyy/master.svg)](https://coveralls.io/r/xxx/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/coverage.png',
                docDescription: ''
            },
            climate:{
                check: function(packageJson){ 
                    return packageJson['qa-control'].coverage || ! packageJson['qa-control'].purpose;
                },
                md:'[![climate](https://img.shields.io/codeclimate/github/xxx/yyy.svg)](https://codeclimate.com/github/xxx/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/climate.png',
                docDescription: ''
            },
            dependencies:{
                mandatory:true,
                md:'[![dependencies](https://img.shields.io/david/xxx/yyy.svg)](https://david-dm.org/xxx/yyy)',
                imgExample:'https://raw.githubusercontent.com/codenautas/codenautas/master/img/medalla-ejemplo-dependencies.png',
                docDescription: ''
            },
            'qa-control':{
                mandatory:true,
                md:'[![qa-control](http://codenautas.com/github/xxx/yyy.svg)](http://codenautas.com/github/xxx/yyy)',
                docDescription: ''
            }
        },
        customs:{
            softRegExp:function(realRegex) {
                var re=realRegex.replace(/\\/g, '\\\\')
                                .replace(/\s*(=+)\s*/g,'\\s*$1\\s*')
                                .replace(/ /g, '\\s+')
                                .replace(/\(/g, '\\(')
                                .replace(/\)/g, '\\)');
                return new RegExp(re, 'im');
            },
            funtion_eid:{
                detect:'function eid',
                match:'function eid(id){ return document.getElementById(id); }'
            },
            var_winos:{
                // separo los siguientes dos strings en dos partes para que no salte un warning
                detect:'var '+'winos=',
                match:"var "+"winOS = Path.sep==='\\\\';"
            },
            var_path:{
                detect:'var path=',
                match:"var Path = require('path');"
            }
        },
        jshint_options: { "asi": false, "curly": true, "forin": true },
        eslint_options: {
            "env": {
              "node": false
            },
            "rules": {
              "strict": 0,
              "no-console": 1,
              "no-unused-vars": 1
            }
        },
        // Si info.scoring == true, cada regla debe agregar junto al warning, un objeto 'scoring'
        // con na o m�s de las siguientes propiedades:
        //   qac: 1
        //   mandatories: 1
        //   cucardas:1
        //   multilang:1
        //   versions:1
        //   parameters:1
        //   format:1
        //   customs:1
        //   jshint:1
        //   dependencies:1
        // Emilio redefinir� valores de cada score
        rules:{
            exist_package_json:{
                checks:[{
                    warnings:function(info){
                        if(!info.files['package.json']){
                            return [{warning:'no_package_json', scoring:{mandatories:1}}];
                        }
                        return [];
                    }
                }],
                shouldAbort:true
            },
            qa_control_section_in_package_json:{
                checks:[{
                    warnings:function(info){
                        if(!info.packageJson['qa-control']){
                            return [{warning:info.files['package.json'].content.match(/codenautas/)?
                                        'no_qa_control_section_in_codenautas_project':
                                        'no_qa_control_section_in_package_json', scoring:{qac:1}}];
                        }
                        return [];
                    }
                }],
                shouldAbort:true
            },
            package_version_in_qa_control_section:{
                checks:[{
                    warnings:function(info){
                        if(!info.packageJson['qa-control']['package-version']){
                            return [{warning:'no_package_version_in_qa_control_section', scoring:{qac:1}}];
                        } else {
                            // defino la version para para siguientes checks
                            info.packageVersion = info.packageJson['qa-control']['package-version'];
                        }
                        return [];
                    }
                }],
                shouldAbort:true
            },
            invalid_qa_control_version: {
                checks:[{
                    warnings:function(info){
                        var ver=info.packageVersion;
                        if(! semver.valid(ver)){
                            return [{warning:'invalid_qa_control_version',params:[ver], scoring:{versions:1}}];
                        }
                        return [];
                    }
                }],
                shouldAbort:true
            },
            deprecated_control_version: {
                checks:[{
                    warnings:function(info) {
                        var ver=info.packageVersion;
                        if(semver.satisfies(ver, qaControl.deprecatedVersions)){
                            return [{warning:'deprecated_qa_control_version',params:[ver], scoring:{versions:1}}];
                        }
                        return [];
                    }
                }],
                shouldAbort:true
            },
            mandatory_files:{
                checks:[{
                    warnings:function(info) {
                        var warns =[];
                        var files=qaControl.projectDefinition[info.packageVersion].files;
                        for(var fileName in files) {
                            if(files.hasOwnProperty(fileName)) {
                                var file = files[fileName];
                                if(file.mandatory && !info.files[fileName]) {
                                    warns.push({warning:'lack_of_mandatory_file_1', params:[fileName], scoring:{mandatories:1}});
                                } else {
                                    if(file.presentIf && file.presentIf(info.packageJson) && !info.files[fileName]) {
                                        warns.push({warning:'lack_of_mandatory_file_1', params:[fileName], scoring:{mandatories:1}});
                                    }
                                }
                            }
                        }
                        return warns;
                    }
                }],
                shouldAbort:true
            },
            repository_in_package_json:{
                checks:[{
                    warnings:function(info) {
                        var warns = [];
                        if(!('repository' in info.packageJson)) {
                            warns.push({warning:'lack_of_repository_section_in_package_json', scoring:{mandatories:1}});
                        } else {
                            if(! qaControl.getRepositoryUrl(info.packageJson).match(/^([-a-zA-Z0-9_.]+\/[-a-zA-Z0-9_.]+)$/)){
                                return [{warning:'repository_name_not_found', scoring:{mandatories:1}}];
                            }
                        }
                        return warns;
                    }
                }],
                shouldAbort:true
            },
            valid_values_for_qa_control_keys:{
                checks:[{
                    warnings:function(info){
                        var warns=[];
                        var qaControlSection=info.packageJson['qa-control'];
                        var sections=qaControl.projectDefinition[info.packageVersion].sections;
                         /*jshint forin: false */
                        for(var sectionName in sections){
                            var sectionDef=sections[sectionName];
                            if(sectionDef.mandatory && !(sectionName in qaControlSection)){
                                warns.push({warning:'lack_of_mandatory_section_1',params:[sectionName], scoring:{mandatories:1}});
                            }else{
                                var observedValue=qaControlSection[sectionName];
                                if(sectionDef.values && !(observedValue in sectionDef.values)){
                                    warns.push({warning:'invalid_value_1_in_parameter_2',params:[observedValue,sectionName], scoring:{parameters:1}});
                                }
                            }
                        }
                         /*jshint forin: true */
                        return warns;
                    }
                }],
                shouldAbort:true
            },
            mandatory_lines:{
                checks:[{
                    warnings:function(info) {
                        var warns =[];
                        var files=qaControl.projectDefinition[info.packageVersion].files;
                        for(var fileName in files) {
                            var file=files[fileName];
                            if(file.mandatoryLines) {
                                var fileContent = info.files[fileName].content;
                                file.mandatoryLines.forEach(function(mandatoryLine) {
                                   // agrego '\n' antes para no utilizar expresiones regulares
                                   if(fileContent.indexOf('\n'+mandatoryLine)===-1) {
                                       warns.push({warning:'lack_of_mandatory_line_1_in_file_2',
                                                   params:[mandatoryLine, fileName],
                                                   scoring:{mandatories:1}});
                                   }
                                });
                            }
                        };
                        return warns;
                    }
                }]
            }, // agregar desde ac�
            no_test_in_node_four:{
                checks:[{
                    warnings:function(info){
                        if(info.dotTravis && info.dotTravis.node_js.filter(function(x){ return x[0].match(/[45678]/); }).length<2){
                            return [{warning:'no_test_in_node_four', scoring:{versions:1}}];
                        }
                        return [];
                    }
                }],
            },
            no_multilang_section_in_1:{
                checks:[{
                    warnings:function(info){
                        if(!info.files[qaControl.mainDoc()].content.match(/<!--multilang v[0-9]+\s+(.+)(-->)/)) {
                            return [{
                                warning:'no_multilang_section_in_1', 
                                params:[qaControl.mainDoc()], 
                                scoring:{multilang:1}
                            }];
                        }
                        return [];
                    }
                }]
            },
            invalid_repository_in_package_json:{
                checks:[{
                    warnings:function(info) {
                        var warns = [];
                        var repoParts = qaControl.getRepositoryUrl(info.packageJson).split('/');
                        var projName = repoParts[repoParts.length-1];
                        if(projName !== info.packageJson.name) {
                            return [{warning:'invalid_repository_section_in_package_json', scoring:{format:1}}];
                        }
                        return warns;
                    }
                }]
            },
            cucardas:{
                eclipsers:['invalid_repository_section_in_package_json', 'lack_of_repository_section_in_package_json'],
                checks:[{
                    warnings:function(info){
                        var warns=[];
                        var readme=info.files[qaControl.mainDoc()].content;
                        if(readme.indexOf(qaControl.cucaMarker) === -1) {
                            warns.push({warning:'lack_of_cucarda_marker_in_readme'});
                        }
                        var cucardas=qaControl.projectDefinition[info.packageVersion].cucardas;
                        var modulo=info.packageJson.name;
                        var repo=qaControl.getRepositoryUrl(info.packageJson).replace('/'+modulo,'');
                         /*jshint forin: false */
                        for(var nombreCucarda in cucardas) {
                            var cucarda = cucardas[nombreCucarda];
                            var cucaID = '!['+/!\[([-a-z]+)]/.exec(cucarda.md)[1]+']';
                            var cucaStr = cucarda.md.replace(/\bxxx\b/g,repo).replace(/\byyy\b/g,modulo);
                            if(readme.indexOf(cucaID) === -1) {
                                if(cucarda.mandatory) {
                                    warns.push({warning:'lack_of_mandatory_cucarda_1', params:[nombreCucarda], scoring:{cucardas:1}});
                                }
                            } else {
                                if('check' in cucarda && ! cucarda.check(info.packageJson)) {
                                    warns.push({warning:'wrong_format_in_cucarda_1', params:[nombreCucarda], scoring:{cucardas:1}});
                                }
                                if(readme.indexOf(cucaStr) === -1) {
                                    // si tengo cucarda mal formada, devuelvo warning aunque no sea obligatoria
                                    // porque existi� la intenci�n de definirla
                                    warns.push({warning:'wrong_format_in_cucarda_1', params:[nombreCucarda], scoring:{cucardas:1}});
                                }
                            }
                        }
                         /*jshint forin: true */
                        if(warns.length || qaControl.cucardas_always) {
                            fs.writeFile(Path.normalize(info.projectDir+'/cucardas.log'), qaControl.generateCucardas(cucardas, info.packageJson));
                        }
                        return warns;
                    }
                }]
            },
            customs:{
                checks:[{
                    warnings:function(info) {
                        var warns=[];
                        var customs = qaControl.projectDefinition[info.packageVersion].customs;
                        function makeCheck(strOrRegexp, isMatchFunc) {
                            var checker;
                            if(!strOrRegexp){
                                checker=function() { return false; };
                            }else if(strOrRegexp instanceof RegExp) {
                                checker=function(str) {
                                    return strOrRegexp.test(str);
                                };
                            } else {
                                checker=function(str) {
                                    if(isMatchFunc) {
                                        return str.indexOf(strOrRegexp) !== -1;
                                    } else {
                                        return customs.softRegExp(strOrRegexp).test(str);
                                    }
                                };
                            }
                            return checker;
                        }
                        for(var file in info.files) {
                            if(file.match(/(.js)$/)) {
                                for(var customeName in customs) {
                                    if(customs.hasOwnProperty(customeName)) {
                                        var content = info.files[file].content;
                                        var custom = customs[customeName];
                                        var detect = makeCheck(custom.detect);
                                        var match = makeCheck(custom.match, true);
                                        //console.log(file, " detect:", detect(content), " match: ", match(content))
                                        if(detect(content) && ! match(content)) {
                                            warns.push({warning:'file_1_does_not_match_custom_2', params:[file,customeName], scoring:{customs:1}});
                                        }
                                    }
                                }
                            }
                        }
                        return warns;
                    }
                }]
            },
            first_lines:{
                checks:[{
                    warnings:function(info) {
                        var warns=[];
                        var qaControlSection=info.packageJson['qa-control'];
                        var whichRunIn=qaControlSection['run-in'];
                        var whichType=qaControlSection.type;
                        var firstLines=qaControl.projectDefinition[info.packageVersion].firstLines[whichRunIn][whichType];
                        if(firstLines) {
                            var ProjectName = qaControl.jsProjectName(info.packageJson.name);
                            var projectName = qaControl.first("toLowerCase")(ProjectName);
                            var mainName = ('main' in info.packageJson) ? info.packageJson.main : 'index.js';
                            if(!(mainName in info.files)) {
                                warns.push({warning:'packagejson_main_file_1_does_not_exists', params:[mainName], scoring:{customs:1}});
                            } else {
                                var fileContent = stripBom(info.files[mainName].content);

                                if(!qaControl.startsWith(fileContent, firstLines.replace(/nombreDelModulo/g, ProjectName)) && 
                                      !qaControl.startsWith(fileContent, firstLines.replace(/nombreDelModulo/g, projectName))
                                ) {
                                    if(qaControl.verbose){
                                        var code=qaControl.fixEOL(fileContent);
                                        var model1=qaControl.fixEOL(firstLines.replace(/nombreDelModulo/g, projectName));
                                        var model2=qaControl.fixEOL(firstLines.replace(/nombreDelModulo/g, ProjectName));
                                        for(var i=0; i<model1.length; i++){
                                            if(code[i]!== model1[i] && code[i] !== model2[i]){
                                                console.log('RUN-IN', whichRunIn);
                                                console.log('DIF STARTS IN:',JSON.stringify(code.substring(i, Math.min(model1.length, i+20))));
                                                console.log('MODEL 1      :',JSON.stringify(model1.substring(i, Math.min(model1.length, i+20))));
                                                console.log('MODEL 2      :',JSON.stringify(model2.substring(i, Math.min(model1.length, i+20))));
                                                console.log('FOR MODULE NAME:',projectName,'OR',ProjectName);
                                                break;
                                            }
                                        }
                                    }
                                    warns.push({warning:'first_lines_does_not_match_in_file_1', params:[mainName], scoring:{warning:1}});
                                }
                            }
                        }
                        return warns;
                    }
                }]
            },
            normal_promises:{
                checks:[{
                    warnings:function(info){
                        var warns = [];
                        for(var file in info.files) {
                            if(file.match(/(.js)$/)) {
                                var content = info.files[file].content;
                                if(content.match(/require\(["'](promise|q|rsvp|es6promise)['"]\)/m)) {
                                    warns.push({warning:'using_normal_promise_in_file_1', params:[file], scoring:{customs:1}});
                                }
                            }
                        }
                        return warns;
                    }
                }]
            },
            jshint_config:{
                checks:[{
                    warnings:function(info){
                        return qaControl.checkLintConfig(info,
                                                         'jshintConfig',
                                                         'lack_of_jshintconfig_section_in_package_json',
                                                         qaControl.projectDefinition[info.packageVersion].jshint_options,
                                                         'incorrect_jshintconfig_option_1_in_package_json',
                                                         {jshint:1});
                    }
                }]
            },
            eslint_config:{
                checks:[{
                    warnings:function(info){
                        return qaControl.checkLintConfig(info,
                                                         'eslintConfig',
                                                         'lack_of_eslintconfig_section_in_package_json',
                                                         qaControl.projectDefinition[info.packageVersion].eslint_options,
                                                         'incorrect_eslintconfig_option_1_in_package_json',
                                                         {eslint:1});
                    }
                }]
            },
            jshint:{
                eclipsers:['packagejson_main_file_1_does_not_exists', 'first_lines_does_not_match_in_file_1',
                           'lack_of_jshintconfig_section_in_package_json', 'incorrect_jshintconfig_option_1_in_package_json'],
                checks:[{
                    warnings:function(info){
                        var warns = [];
                        var jshintOpts = 
                            info.packageJson.jshintConfig || 
                            qaControl.projectDefinition[info.packageVersion].jshint_options;
                        for(var file in info.files) {
                            if(file.match(/(.js)$/)) {
                                var content = info.files[file].content;
                                jsh.JSHINT(content, jshintOpts , false);
                                var data = jsh.JSHINT.data();
                                if(data.errors) {
                                    if(qaControl.verbose){
                                        console.log('JSHINT output:');
                                        console.log('jshintOpts',jshintOpts);
                                        console.log(data.errors.length, " JSHINT errors");
                                        console.log(data.errors);
                                        //console.log(data);
                                    }
                                    warns.push({warning:'jshint_warnings_in_file_1', params:[file], scoring:{jshint:1}});
                                }
                            }
                        }
                        return warns;
                    }
                }]
            },
            eslint:{
                eclipsers:['packagejson_main_file_1_does_not_exists', 'first_lines_does_not_match_in_file_1',
                           'lack_of_eslintconfig_section_in_package_json', 'incorrect_eslintconfig_option_1_in_package_json'],
                checks:[{
                    warnings:function(info){
                        var warns = [];
                        var eslintOpts = 
                            info.packageJson.eslintConfig || 
                            qaControl.projectDefinition[info.packageVersion].eslint_options;
                        for(var file in info.files) {
                            if(file.match(/(.js)$/)) {
                                var content = info.files[file].content;
                                var data = esl.linter.verify(content, eslintOpts);
                                if(data.length) {
                                    if(qaControl.verbose){
                                        console.log('ESLINT output:');
                                        console.log('eslintOpts',eslintOpts);
                                        console.log(data.length, " ESLINT errors");
                                        console.log(data);
                                        //console.log(data);
                                    }
                                    warns.push({warning:'eslint_warnings_in_file_1', params:[file], scoring:{eslint:1}});
                                }
                            }
                        }
                        return warns;
                    }
                }]
            },
            multilang:{
                checks:[{
                    warnings:function(info) {
                        var warns = [];
                        var defReadme = qaControl.mainDoc();
                        var content = info.files[defReadme].content;
                        var obtainedLangs = multilang.obtainLangs(content);
                        /*jshint forin: false */
                        for(var lang in obtainedLangs.langs) {
                            var file=obtainedLangs.langs[lang].fileName;
                            if(file !== defReadme) {
                                var mlContent = multilang.changeNamedDoc(file, content, lang);
                                if(mlContent !== info.files[file].content) {
                                    warns.push({warning:'readme_multilang_not_sincronized_with_file_1', params:[file], scoring:{multilang:1}});
                                }
                            }
                        }
                        /*jshint forin: true */
                        return warns;
                    }
                }]
            },
            dependencies:{
                checks:[{
                    warnings:function(info) {
                        var warns = [];
                        if("dependencies" in info.packageJson) {
                            var reDep=/^~?\d+\.\d+\.\d+$/;
                            /*jshint forin: false */
                            for(var depName in info.packageJson.dependencies) {
                                var depVal = info.packageJson.dependencies[depName];
                                if(! reDep.test(depVal)) {
                                    // console.log(depName, depVal);
                                    warns.push({warning:'invalid_dependency_version_number_format_in_dep_1', params:[depName], scoring:{dependencies:1}});
                                }
                            }
                            /*jshint forin: true */
                        }
                        return warns;
                    }
                }]
            },
            use_strict:{
                checks:[{
                    warnings:function(info){
                        var warns = [];
                        for(var file in info.files) {
                            if(file.match(/(.js)$/)) {
                                var content = info.files[file].content;
                                var lines = info.files[file].content.split(/\r?\n/);
                                var prevLine = null;
                                for(var l=0; l<lines.length; ++l) {
                                    var line = lines[l];
                                    var trimLine = line.replace(/^(\s+)/,'');
                                    //console.log("line:"+l, '['+line+']', "trimmed", '['+trimLine+']', "prev", '['+prevLine+']');
                                    if(trimLine.length>0
                                        && trimLine[0].match(/['"']/)
                                        && prevLine
                                        && prevLine.match(/{$/)
                                        && ! prevLine.match(/[a-zA-Z0-9_]+\s?:/)
                                        )
                                    {
                                        if(! trimLine.match(/"use strict";/)) {
                                            if(qaControl.verbose){
                                                console.log('['+file+']');
                                                console.log('  '+(l-1)+':"'+prevLine+'"');
                                                console.log('  '+(l)+':"'+line+'"');
                                            }
                                            warns.push({warning:'wrong_use_strict_spelling_in_file_1', params:[file], scoring:{customs:1}});
                                        }
                                    }
                                    prevLine = line;
                                }
                            }
                        }
                        return warns;
                    }
                }]
            }
        }
    };
};