cloudchen / grunt-template-jasmine-requirejs

RequireJS template for grunt-contrib-jasmine task
111 stars 96 forks source link

Issue where the use of paths config would throw an "Illegal path Error" #27

Closed tansart closed 10 years ago

tansart commented 11 years ago

When testing modules that rely on paths config, requirejs would throw this following error: Error: scripterror: Illegal path or script error:

I fixed it by checking for existing paths config in the requireConfigFile. If any, it uses the paths config in the outer-most require call (instead of the normal path):

require([*when available, uses paths config here*], function() {
  require([*YOUR SPECS*], function() {
    ...
  }
}

This fixes the issue, but then fails when you have a mix of paths and paths config. Here's my fork

Thoughts?

jgauna commented 11 years ago

Hi Stilva,

I'm trying to run the jasmine test but it's failing because of this (I think):

              requireConfig: {
>               baseUrl: '../scripts/',
                paths: {
                  "jquery": "../scripts/vendors/jquery"
                },
                shim: {
                  /*'foo': {
                    deps: ['bar'],
                    exports: 'Foo',
                    init: function (bar) {
                      return this.Foo.noConflict();
                    }
                  }*/
                },
                deps: ['jquery'],
                callback: function($) {
                  // do initialization stuff
                  /*

                  */
                }
              }

Is there any work around to solve the issue when the baseUrl is one step behind of the tests folder?

I'm getting this error:

>> Error: scripterror: Illegal path or script error:
- MyWebProject
  - scriptsToTestFolder
  - testSuiteFolder
    - Gruntfile.js (with jasmine configuration)

Regards, Juan.

vorakumar commented 11 years ago

The paths in the configuration are defined with respect to bas url (and not tests dir). So in your example, path for jQuery would be: jquery:"vendors/jquery"

Hi Stilva,

I'm trying to run the jasmine test but it's failing because of this (I think):

          requireConfig: {
          baseUrl: '../scripts/',
            paths: {
              "jquery": "../scripts/vendors/jquery"
            },
            shim: {
              /*'foo': {
                deps: ['bar'],
                exports: 'Foo',
                init: function (bar) {
                  return this.Foo.noConflict();
                }
              }*/
            },
            deps: ['jquery'],
            callback: function($) {
              // do initialization stuff
              /*
              */
            }
          }

Is there any work around to solve the issue when the baseUrl is one step behind of the tests folder?

Regards, Juan.

— Reply to this email directly or view it on GitHubhttps://github.com/jsoverson/grunt-template-jasmine-requirejs/issues/27#issuecomment-20438966 .

jgauna commented 11 years ago

Sorry, my bad explaining.

This is the same config file that I have in my project

module.exports = function(grunt) {
'use strict';

grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
        //package: grunt.file.readJSON('package.json'),
        src: {
            main: '../',
            test: 'test/tests'
        },
        bin: {
            coverage: 'test/reports'
        }
    },
    jasmine : {
        requirejs: {
          src: '../scripts/router.js',
          options: {
            specs: 'test/tests/*Test.js',
            // helpers: 'spec/*Helper.js',
            //  host: 'http://127.0.0.1:8000/',
            template: require('grunt-template-jasmine-requirejs'),
            templateOptions: {
              requireConfigFile: '../scripts/main.js',
              requireConfig: {
                baseUrl: '../scripts/',
                paths: {
                  "jquery": "../scripts/vendors/jquery"
                },
                shim: {
                  /*'foo': {
                    deps: ['bar'],
                    exports: 'Foo',
                    init: function (bar) {
                      return this.Foo.noConflict();
                    }
                  }*/
                },
                deps: ['jquery'],
                callback: function($) {
                  // do initialization stuff
                  /*

                  */
                }
              }

          }
        }
      },
        coverage: {
            src: ['mockedSrcFolder/*.js'],
            options: {
                specs: ['test/tests/*Test.js'],
                template: require('grunt-template-jasmine-istanbul'),
                templateOptions: {
                    coverage: 'test/reports/coverage.json',
                    report: 'test/reports',
                    thresholds: {
                        lines: 75,
                        statements: 75,
                        branches: 75,
                        functions: 90
                    }
                }
            }
        },
        templateOptions: {
            requireConfig: {
                baseUrl: '../scripts',
                paths: {
                'jquery': '../scripts/vendor/jquery'
                }
            }
        },
        errorReporting: true
    }
});

    grunt.loadNpmTasks('grunt-contrib-jasmine');    // jgauna
    grunt.loadNpmTasks('grunt-contrib-jshint'); // jgauna
    //grunt.registerTask('test', ['jasmine']);  // jgauna
          grunt.registerTask('test', ['jasmine:requirejs']);
    grunt.loadTasks('tasks');   //tcampodonico-dpacheco

};

So, when I run it with grunt test, I get:

>> Error: scripterror: Illegal path or script error: ['C:/xampp/htdocs/deloitte/gen-test/backbone-example/scripts/router'] at
>> ..\..\..\..\..\..\C:\xampp\htdocs\deloitte\gen-test\backbone-example\test-suite\_SpecRunner.html:21
>> ..\..\..\..\..\..\C:\xampp\htdocs\deloitte\gen-test\backbone-example\test-suite\.grunt\grunt-contrib-jasmine\require.js:12 v
>> ..\..\..\..\..\..\C:\xampp\htdocs\deloitte\gen-test\backbone-example\test-suite\.grunt\grunt-contrib-jasmine\require.js:29

The router.js file is located in the folder behind (We are creating a test suite generator, so all the files are placed in a directory inside the project to test). The structure's something like this:

- ProjectWeb
  - scripts
    - router.js
  - testUnitGenerator
    - Gruntfile.js
    - package.json
    - anythingElse.file

The idea is to test the router.js file running grunt test from the testUnitGenerator folder.

Hope to be clear,

Regards Thanks a lot! jgauna.

tansart commented 11 years ago

Regarding the issue I was having 804f88.

@jgauna, In your case, there are a few issues:

1 . In grunt-contrib-jasmine, go to tasks/lib/jasmine.js and make the following amendements (line ~103):

files = grunt.util._(files).map(function(file) {

  // return (/^https?:/).test(file) ? file : path.resolve(file).replace(base,'.').replace(/\\/g,'/');
  return (/^https?:/).test(file) ? file : path.relative(base, file).replace(/\\/g,'/');
});

This fixes the issue where requirejs is given a local path – which obviously fails in phantomjs.

2 . It seems requirejs doesn't like relative paths issue #550, so even with the above fixed, you'll still have some issue.

Using connect and express you could re-route requests to localhost:8000/scripts/* to path/to/scripts In your Gruntfile.js:

var express = require("express");
[...]
//within grunt.initConfig:
connect: {
  test: {
    options: {
      port: 8000,
      base: '.',
      middleware: function(connect, options) {
        return [
          connect.static(options.base),
          connect.directory(options.base),
          ("/scripts/*", express.static(__dirname+"/../"))
        ];
      }
    }
  }
},

Hope that helps!

jgauna commented 11 years ago

do you have an example of express configuration in a gruntfile? I am a little sutcked with this!

Should I use https://github.com/blai/grunt-express ?

Thanks a lot !

jgauna commented 11 years ago

Hey, it's finally working !

Thanks a lot for your help,

Regards, jgauna.

MartijnR commented 11 years ago

Am having a similar issue (the error is similar). My tests run fine locally in the terminal (though it was odd, that I had to add a trailing slash to the app path) but fail in Travis. It seems the path app is not translated in Travis.

this is the config in the Gruntfile:

jasmine: {
      test: {
        src: 'src/**/*.js',
        options: {
          specs: 'test/spec/*.js',
          helpers: [ 'test/util/*.js', 'test/mock/*.js' ],
          template: require('grunt-template-jasmine-requirejs'),
          templateOptions: {
            requireConfig: {
              baseUrl: 'lib',
              paths: {
>               app:   '../src/js/' //fails on local terminal without trailing slash
              },
              shim: {
                'xpath/build/xpathjs_javarosa': {
                  exports: 'XPathJS'
                },
                'bootstrap-datepicker/js/bootstrap-datepicker': {
                  deps: [ 'jquery' ],
                  exports: 'jQuery.fn.datepicker'
                },
                'bootstrap-timepicker/js/bootstrap-timepicker': {
                  deps: [ 'jquery' ],
                  exports: 'jQuery.fn.timepicker'
                }
              }
            }
          }
        },
      }

This is the Travis error (full report here):

Running "jasmine:test" (jasmine) task
Testing jasmine specs via phantom
>> Error: scripterror: Illegal path or script error: ['app/Form'] at
>> _SpecRunner.html:21 
>> .grunt/grunt-contrib-jasmine/require.js:12 v
>> .grunt/grunt-contrib-jasmine/require.js:29 

Any ideas on what could possible cause this or advice on where I should look for the issue?

cloudchen commented 11 years ago

Add one more map configuration to your requireConfig.

map: {
    '*': {
        "app": "../src/js"
    }
}

This mapping only needs to be added for jasmine task. Development environment doesn't have to.

MartijnR commented 11 years ago

Thanks @cloudchen Still a Travis build issue (similar but different), but I no longer require a trailing slash.

Am still a noob with requirejs, but it seems that, strictly speaking, I shouldn't actually require the map parameter, right?

cloudchen commented 11 years ago

Am still a noob with requirejs, but it seems that, strictly speaking, I shouldn't actually require the map parameter, right?

Yes, only this template needs it.

MartijnR commented 11 years ago

My remaining issue with illegal path errors was related to capitalization (tried to load Form.js, when the file was named form.js. OS X tolerated this error but the Travis VM did not.)

vjtyagi commented 10 years ago

@cloudchen I think you should document this. map: { '*': { "app": "../src/js" } }

I almost pulled my hair out trying to figure out the reason for load failure.

In my requirejs config i had paths like

paths:{ "mainmodels" : "org/example/domain/models" //basically short hand paths to directories. }

and in my modules i was refering to the modules like this

/* module.js * / define(["mainmodels/BaseModel"], function(BaseModel){ //some code });

this approach works fine with normal requirejs but i had a hard time loading the "src" files with references like "mainmodels".

however, explicit mapping did solve the problem.

amireh commented 10 years ago

None of the solutions here really gave me what I wanted. I either had to load a dependency twice, or rewrite the path config, and neither seemed pretty.

I ended up modifying the template to simply load the helper scripts after require.js has been configured and now everything works as expected: the helpers will use the correct paths to all the source scripts, plus any you custom paths you define that are test-exclusive.

Check out the 0.1.9 release in my fork https://github.com/amireh/grunt-template-jasmine-requirejs and if you like the options, I can submit a pull request.

cloudchen commented 10 years ago

Try v0.1.10 to see whether it is fixed