cloudchen / grunt-template-jasmine-requirejs

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

How to use this with fixture data? #22

Closed Integralist closed 11 years ago

Integralist commented 11 years ago

Hi,

Below is my current set-up for Jasmine on a work project, but I'm not sure how best to get this running so that I can load individual fixture files (e.g. HTML/DOM structures to test against)?

jasmine: {
    src: ['./tablod/webapp/static/js/**/*.js', '!./tablod/webapp/static/js/compiled/**'],
    options: {
        specs: './tablod/webapp/static/js/specs/**/*Spec.js',
        helpers: ['./tablod/webapp/static/js/specs/helpers/*Helper.js', './tablod/webapp/static/js/specs/helpers/sinon.js'],
        template: require('grunt-template-jasmine-requirejs'),
        templateOptions: {
            requireConfig: {
                baseUrl: './tablod/webapp/static/js/',
                paths: {
                    'jquery': 'vendor/jquery-2/jquery.min',
                    'domReady': 'vendor/require/domReady',
                    'translation': 'module/translations/news'
                },
                exclude: ['config', 'jquery' ],
                name: 'define',
                out: 'compiled/all.js'
            }
        }
    }
}

In the above example define is actually a file define.js which loads all our modules (for the purpose of building/concatenating it into a single all.js) and it looks like this...

define([
    'module/a/foo',
    'module/b/bar',
        'module/c/baz'
        ...loads more modules...
], function() {
  return '';
});

How would I go about splitting this up and loading a fixture file for each module? I'd like to have a set of HTML files that require() in the relevant modules and which I can call via Grunt Jasmine.

Any ideas? Appreciate any help I can get.

Thanks.

Integralist commented 11 years ago

UPDATE: I have an idea of how I want to achieve this but it's not working?

I want to run a localserver using grunt-contrib-connect and to create my HTML fixture data and append to the DOM (the DOM provided by the localserver) and then I can test against that.

But I'm not sure how to run the connect task (or specifically how it ties into this jasmine-requirejs task)?

Below is an updated Gruntfile with relevant connect and host options set. Below that is the _SpecRunner file that was created automatically.

connect: {
            test: {
                port: 8000
            }
        },

        jasmine: {
            src: ['./tabloid/webapp/static/js/**/*.js', '!./tabloid/webapp/static/js/tests/**/*.js', './tabloid/webapp/static/js/specs/helpers/**/*.js', '!./tabloid/webapp/static/js/build.js'],
            options: {
                specs: './tabloid/webapp/static/js/specs/**/*Spec.js',
                helpers: ['./tabloid/webapp/static/js/specs/helpers/*Helper.js', './tabloid/webapp/static/js/specs/helpers/sinon.js'],
                host: 'http://127.0.0.1:8000/',
                template: require('grunt-template-jasmine-requirejs'),
                templateOptions: {
                    requireConfig: {
                        baseUrl: './tabloid/webapp/static/js/',
                        paths: {
                            'jquery': 'vendor/jquery-2/jquery.min',
                            'domReady': 'vendor/require/domReady',
                            'translation': 'module/translations/news'
                        },
                        exclude: ['config', 'jquery' ],
                        name: 'define',
                        out: './tabloid/webapp/static/js/compiled/all.js'
                    }
                }
            }
        }

and the automatically generated SpecRunner...

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Jasmine Spec Runner</title>

  <link rel="stylesheet" type="text/css" href=".grunt/grunt-contrib-jasmine/jasmine.css">

  <script src="./.grunt/grunt-contrib-jasmine/jasmine.js"></script>

  <script src="./.grunt/grunt-contrib-jasmine/jasmine-html.js"></script>

  <script src="./tabloid/webapp/static/js/specs/helpers/SpecHelper.js"></script>

  <script src="./tabloid/webapp/static/js/specs/helpers/sinon.js"></script>

  <script>

      var require = {
  "baseUrl": "./tabloid/webapp/static/js/",
  "paths": {
    "jquery": "vendor/jquery-2/jquery.min",
    "domReady": "vendor/require/domReady",
    "translation": "module/translations/news"
  },
  "exclude": [
    "config",
    "jquery"
  ],
  "name": "define",
  "out": "./tabloid/webapp/static/js/compiled/all.js"
};

  </script>

  <script>
  function launchTest() {
    require([

        'bootstrap-ui' ,

        'compiled/all' ,

        'config' ,

        'define' ,

        'deviceInspector' ,

        'locator/autoCompleteView' ,

        'locator/autoCompleteView.js ' ,

        'locator/bootstrap' ,

        'locator/bootstrap_desktop' ,

        'locator/locatorView' ,

        'locator/main' ,

        'locator/stats' ,

        'module/ajaxForm/ajaxForm' ,

        'module/ajaxForm/ajaxFormView' ,

        'module/analytics/analytics_client' ,

        'module/base' ,

        'module/bootstrap-desktop' ,

        'module/bootstrap' ,

        'module/components/featuresAndAnalysis' ,

        'module/components/mostPopular' ,

        'module/components/topStoriesPromo' ,

        'module/deviceInspector' ,

        'module/featureDetector' ,

        'module/fontface' ,

        'module/history/hashed' ,

        'module/history/history' ,

        'module/history/native' ,

        'module/hyperpuff/hyperpuff' ,

        'module/hyperpuff/minihyper' ,

        'module/imageenhancer' ,

        'module/index' ,

        'module/live-event-component' ,

        'module/live-event' ,

        'module/liveEvent/timeline' ,

        'module/liveEvent/timelineView' ,

        'module/local/local' ,

        'module/local/localView' ,

        'module/localnewsandweather' ,

        'module/media/empFacade' ,

        'module/media/mediaHandler' ,

        'module/media/mediaLoader' ,

        'module/media/mediaRegistry' ,

        'module/media/piratePlayer' ,

        'module/media/piratePlayerView' ,

        'module/mediaAssetPage/api' ,

        'module/mediaAssetPage/assetView' ,

        'module/mediaAssetPage/listView' ,

        'module/mediaAssetPage/map' ,

        'module/mediaAssetPage/mediaAssetPage' ,

        'module/mediaAssetPage/pinningView' ,

        'module/nav/nav' ,

        'module/nav/navManager' ,

        'module/poller' ,

        'module/readabilityCheck' ,

        'module/rollingNews' ,

        'module/stats/siteCatalyst' ,

        'module/stats/statsConfig' ,

        'module/stats/statsSubscriber' ,

        'module/story' ,

        'module/stylesheetloader' ,

        'module/tabbed/panel' ,

        'module/tabbed/tab' ,

        'module/tabbed/tabbed' ,

        'module/timestamp' ,

        'module/transclude' ,

        'module/translations/afrique' ,

        'module/translations/arabic' ,

        'module/translations/hausa' ,

        'module/translations/hindi' ,

        'module/translations/indonesia' ,

        'module/translations/mundo' ,

        'module/translations/news' ,

        'module/translations/russian' ,

        'module/translator' ,

        'module/travel/travel' ,

        'module/travel/travelView' ,

        'module/urlShrinker' ,

        'module/weather/weather' ,

        'module/weather/weatherLocation' ,

        'module/weather/weatherLocationView' ,

        'module/weather/weatherView' ,

        'specs/BasicSpec' ,

        'specs/SinonSpec' ,

        'specs/helpers/SpecHelper' ,

        'specs/helpers/sinon' ,

        'translation' ,

        'translator' ,

        'vendor/events/eventEmitter' ,

        'vendor/istats/istats' ,

        'vendor/jquery-1/jquery' ,

        'vendor/jquery-1/jquery.min' ,

        'vendor/jquery-1/jquery.mockjax' ,

        'vendor/jquery-2/jquery.min' ,

        'vendor/require/domReady' ,

        'vendor/require/require' ,

        'vendor/require/require.min' 

    ],
    function(){
      require(['./tabloid/webapp/static/js/specs/BasicSpec.js','./tabloid/webapp/static/js/specs/SinonSpec.js','./.grunt/grunt-contrib-jasmine/reporter.js'], function(){
        require(['./.grunt/grunt-contrib-jasmine/jasmine-helper.js'], function(){
          // good to go! Our tests should already be running.
        })
      })
    }
    )
  }
  </script>

  <script src=".grunt/grunt-contrib-jasmine/require.js"></script>
  <script>
      require.onError = function(error) {
      var message = error.requireType + ': ';
      if (error.requireType === 'scripterror' || error.requireType === 'notloaded' && error.requireModules) {
        message += 'Illegal path or script error: ' + '[\'' + error.requireModules.join("', '") + '\']';
      } else {
        message += error.message;
      }

      throw Error(message);
    };
  </script>

  <script>
  launchTest();
  </script>

</head>
<body>
</body>
</html>

But if I run grunt jasmine all I get back is...

Running "jasmine:src" (jasmine) task
Testing jasmine specs via phantom

Any ideas?

cloudchen commented 11 years ago

If you want to run spec by standalone server mode, just as you mentioned with grunt-contrib-connect module, then you cann't run grunt jasmine independently.

You should run connect task before jasmin task

grunt.registerTask('test', ['connect', 'jasmine']);

For fixtures, I think it better to load it in spec. For example, load fixture by jasmine-jquery library.

Integralist commented 11 years ago

@cloudchen heya, thanks for the feedback. I've tried your 'test' task solution to see if I could get that working first but that fails for me.

I get the following errors...

Testing jasmine specs via phantom
>> Error: scripterror: Illegal path or script error: ['jquery-1'] at
>> http:/127.0.0.1:8000/_SpecRunner.html:407 
>> http:/127.0.0.1:8000/.grunt/grunt-contrib-jasmine/require.js:12 v
>> http:/127.0.0.1:8000/.grunt/grunt-contrib-jasmine/require.js:29 
>> Error: timeout: Load timeout for modules: translation
>> http://requirejs.org/docs/errors.html#timeout at
>> http:/127.0.0.1:8000/_SpecRunner.html:407 
>> http:/127.0.0.1:8000/.grunt/grunt-contrib-jasmine/require.js:12 v
>> http:/127.0.0.1:8000/.grunt/grunt-contrib-jasmine/require.js:13 D
>> http:/127.0.0.1:8000/.grunt/grunt-contrib-jasmine/require.js:14 

Warning: PhantomJS timed out, possibly due to an unfinished async spec. Use --force to continue.

Aborted due to warnings.

Here is my (updated) generated SpecRunner file...

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Jasmine Spec Runner</title>
<link rel="stylesheet" type="text/css" href=".grunt/grunt-contrib-jasmine/jasmine.css">
<script src="./.grunt/grunt-contrib-jasmine/jasmine.js"></script>
<script src="./.grunt/grunt-contrib-jasmine/jasmine-html.js"></script>
<script src="./tabloid/webapp/static/js/specs/helpers/SpecHelper.js"></script>
<script src="./tabloid/webapp/static/js/specs/helpers/sinon.js"></script>
<script>
      var require = {
  "baseUrl": "./tabloid/webapp/static/js/",
  "paths": {
    "jquery": "vendor/jquery-1/jquery.min",
    "domReady": "vendor/require/domReady",
    "translation": "module/translations/news"
  },
  "name": "define"
};
  </script>
<script>
  function launchTest() {
    require([
        'bootstrap-ui' ,
        'config' ,
        'define' ,
        'deviceInspector' ,
        'locator/autoCompleteView' ,
        'locator/autoCompleteView.js ' ,
        'locator/bootstrap' ,
        'locator/bootstrap_desktop' ,
        'locator/locatorView' ,
        'locator/main' ,
        'locator/stats' ,
        'module/ajaxForm/ajaxForm' ,
        'module/ajaxForm/ajaxFormView' ,
        'module/analytics/analytics_client' ,
        'module/base' ,
        'module/bootstrap-desktop' ,
        'module/bootstrap' ,
        'module/components/featuresAndAnalysis' ,
        'module/components/mostPopular' ,
        'module/components/topStoriesPromo' ,
        'module/deviceInspector' ,
        'module/featureDetector' ,
        'module/fontface' ,
        'module/history/hashed' ,
        'module/history/history' ,
        'module/history/native' ,
        'module/hyperpuff/hyperpuff' ,
        'module/hyperpuff/minihyper' ,
        'module/imageenhancer' ,
        'module/index' ,
        'module/live-event-component' ,
        'module/live-event' ,
        'module/liveEvent/timeline' ,
        'module/liveEvent/timelineView' ,
        'module/local/local' ,
        'module/local/localView' ,
        'module/localnewsandweather' ,
        'module/media/empFacade' ,
        'module/media/mediaHandler' ,
        'module/media/mediaLoader' ,
        'module/media/mediaRegistry' ,
        'module/media/piratePlayer' ,
        'module/media/piratePlayerView' ,
        'module/mediaAssetPage/api' ,
        'module/mediaAssetPage/assetView' ,
        'module/mediaAssetPage/listView' ,
        'module/mediaAssetPage/map' ,
        'module/mediaAssetPage/mediaAssetPage' ,
        'module/mediaAssetPage/pinningView' ,
        'module/nav/nav' ,
        'module/nav/navManager' ,
        'module/poller' ,
        'module/readabilityCheck' ,
        'module/rollingNews' ,
        'module/stats/siteCatalyst' ,
        'module/stats/statsConfig' ,
        'module/stats/statsSubscriber' ,
        'module/story' ,
        'module/stylesheetloader' ,
        'module/tabbed/panel' ,
        'module/tabbed/tab' ,
        'module/tabbed/tabbed' ,
        'module/timestamp' ,
        'module/transclude' ,
        'module/translations/afrique' ,
        'module/translations/arabic' ,
        'module/translations/hausa' ,
        'module/translations/hindi' ,
        'module/translations/indonesia' ,
        'module/translations/mundo' ,
        'module/translations/news' ,
        'module/translations/russian' ,
        'module/translator' ,
        'module/travel/travel' ,
        'module/travel/travelView' ,
        'module/urlShrinker' ,
        'module/weather/weather' ,
        'module/weather/weatherLocation' ,
        'module/weather/weatherLocationView' ,
        'module/weather/weatherView' ,
        'specs/BasicSpec' ,
        'specs/SinonSpec' ,
        'specs/helpers/SpecHelper' ,
        'specs/helpers/sinon' ,
        'translation' ,
        'translator' 
    ],
    function(){
      require(['./tabloid/webapp/static/js/specs/BasicSpec.js','./tabloid/webapp/static/js/specs/SinonSpec.js','./.grunt/grunt-contrib-jasmine/reporter.js'], function(){
        require(['./.grunt/grunt-contrib-jasmine/jasmine-helper.js'], function(){
          // good to go! Our tests should already be running.
        })
      })
    }
    )
  }
  </script>
<script src=".grunt/grunt-contrib-jasmine/require.js"></script>
<script>
      require.onError = function(error) {
      var message = error.requireType + ': ';
      if (error.requireType === 'scripterror' || error.requireType === 'notloaded' && error.requireModules) {
        message += 'Illegal path or script error: ' + '[\'' + error.requireModules.join("', '") + '\']';
      } else {
        message += error.message;
      }
      throw Error(message);
    };
  </script>
<script>
  launchTest();
  </script>
</head>
<body>
</body>
</html>

I think the problem is that I need to ensure jQuery is loaded before the tests? I tried using the [dep] option in RequireJS (see below updated Gruntfile) but that still gave me the same error as above...

connect: {
            test: {
                port: 8000
            }
        },

        jasmine: {
            src: ['./tabloid/webapp/static/js/**/*.js', '!./tabloid/webapp/static/js/tests/**/*.js', './tabloid/webapp/static/js/specs/helpers/**/*.js', '!./tabloid/webapp/static/js/build.js', '!./tabloid/webapp/static/js/compiled/all.js', '!./tabloid/webapp/static/js/vendor/**/*.js'],
            options: {
                specs: './tabloid/webapp/static/js/specs/**/*Spec.js',
                helpers: ['jquery', './tabloid/webapp/static/js/specs/helpers/*Helper.js', './tabloid/webapp/static/js/specs/helpers/sinon.js'],
                host: 'http://127.0.0.1:8000/',
                template: require('grunt-template-jasmine-requirejs'),
                templateOptions: {
                    requireConfig: {
                        baseUrl: './tabloid/webapp/static/js/',
                        paths: {
                            'jquery': 'vendor/jquery-1/jquery.min',
                            'domReady': 'vendor/require/domReady',
                            'translation': 'module/translations/news'
                        },
                        name: 'define',
                        deps: ['jquery'],
                        callback: function($) {
                          console.log('jquery loaded!');
                        }
                    }
                }
            }
        }

If you have an ideas then please let me know.

Thanks.

M.

cloudchen commented 11 years ago

The error hint is clear. Module "jquery-1" is not found by requirejs. This kind of error is requirejs related, not this requirejs template issue. You need to properly configure your requireConfig.

requireConfig: {
...
                        baseUrl: './tabloid/webapp/static/js/',
                        paths: {
                            'jquery-1': '/path/to/jquery-1',
                            'jquery': 'vendor/jquery-2/jquery.min',
                            'domReady': 'vendor/require/domReady',
                            'translation': 'module/translations/news'
                        },
...
}
Integralist commented 11 years ago

@cloudchen ah, sorry that was my bad.

Seems like the basic JS tests I have are running now...

Testing jasmine specs via phantom
Starting...
Basic:should pass a single assertion without causing an error...should pass a single assertion without causing an error: passed
Basic:should let me test our AMD modules...should let me test our AMD modules: passed
AJAX:should demonstrate the Sinon mocking and spying functionality...should demonstrate the Sinon mocking and spying functionality: passed
Sinon.js:should have access to the sinon library...should have access to the sinon library: passed
Sinon.js:should demonstate stub feature...should demonstate stub feature: passed
Sinon.js:should demonstate mock feature...should demonstate mock feature: passed
Basic:should pass a single assertion without causing an error...should pass a single assertion without causing an error: passed
Basic:should let me test our AMD modules...should let me test our AMD modules: passed
AJAX:should demonstrate the Sinon mocking and spying functionality...should demonstrate the Sinon mocking and spying functionality: passed
Sinon.js:should have access to the sinon library...should have access to the sinon library: passed
Sinon.js:should demonstate stub feature...should demonstate stub feature: passed
Sinon.js:should demonstate mock feature...should demonstate mock feature: passed
Runner finished
12 specs in 0.006s.
>> 0 failures

Done, without errors.

I just need to see if I can inject HTML into the DOM and test against that?

Integralist commented 11 years ago

@cloudchen actually, one issue I've just noticed is that it's running the tests twice? It says "12 specs" but there are only 6 and when I run in -v mode I can see the 6 specs are repeated. Any ideas on why that would be?

cloudchen commented 11 years ago

@Integralist I saw repeated spec name twice with -v mode, too. Don't know why.

Integralist commented 11 years ago

@cloudchen it seems the tests were running twice due to my relaxed src directory globs. I've managed to fix that now.

Thanks for your help with this issue!