zurb / foundation-apps

The first front-end framework created for developing fully responsive web apps.
http://foundation.zurb.com/apps
MIT License
1.58k stars 215 forks source link

Unable to run a unit test on a new Foundation for Apps project #423

Closed mattgrande closed 9 years ago

mattgrande commented 9 years ago

(Please note: I'm coming from a Backbone background, so I may not be doing things correctly. If that's the case, please let me know).

I've created a "Foundation For Apps" app by running foundation-app new myApp and am trying to basically follow the Angular PhoneCat tutorial. It started off pretty well, until I got to unit testing...

Trying to run any test (using Jasmine & Karma) on any file results in this error message:

TypeError: Cannot read property 'replace' of null
    at Object.init (/Users/matt/projects/wx-portal/bower_components/foundation-apps/js/angular/services/foundation.core.js:39:79)
    at mqInitRun (/Users/matt/projects/wx-portal/bower_components/foundation-apps/js/angular/services/foundation.core.js:16:12)
    at Object.invoke (/Users/matt/projects/wx-portal/bower_components/angular/angular.js:4182:17)
    at /Users/matt/projects/wx-portal/bower_components/angular/angular.js:4004:71
    at forEach (/Users/matt/projects/wx-portal/bower_components/angular/angular.js:323:20)
    at Object.createInjector [as injector] (/Users/matt/projects/wx-portal/bower_components/angular/angular.js:4004:3)
    at workFn (/Users/matt/projects/wx-portal/bower_components/angular-mocks/angular-mocks.js:2339:52)

This is the code that's throwing the error (foundation.core.js, in the init function):

for(var key in mediaQueries) {
  mediaQueries[key] = 'only screen and (min-width: ' + mediaQueries[key].replace('rem', 'em') + ')';
}

If I change that line to this:

for(var key in mediaQueries) {
  if ( mediaQueries[key] )
    mediaQueries[key] = 'only screen and (min-width: ' + mediaQueries[key].replace('rem', 'em') + ')';
}

...everything runs as expected.

Is this a bug in Foundation For Apps, or am I doing something wrong? I don't really like the idea of changing things in foundation.core.js unless I absolutely have to...

gakimball commented 9 years ago

The template stack doesn't come with any unit tests; are you writing your own?

mattgrande commented 9 years ago

Yes; Jasmine tests being run with Karma (although the results are the same with or without Karma).

gakimball commented 9 years ago

Hm, could you post the tests you've written?

mattgrande commented 9 years ago

I'll do you one better. You can clone this repo to reproduce the issue:
https://github.com/mattgrande/foundation-apps-unit-test-issue

$ git clone https://github.com/mattground/foundation-apps-unit-test-issue.git
$ cd foundation-apps-unit-test-issue
$ npm install
$ gulp test
gakimball commented 9 years ago

Thanks for the repo link; taking a look at this today.

gakimball commented 9 years ago

Well, I got a totally different set of errors when I tried to run the tests, but either way I think I might know the problem.

When the Sass is compiled to CSS, it drops the media query list into a property with a meta selector. The JavaScript then injects a <meta> tag with the same class and parses the value. If the test suite doesn't have a finished CSS file to reference, it can't read those values, which is why the mediaQueries object comes up null.

mattgrande commented 9 years ago

So... is there anything I should do about this from a test point of view, or should I just not reference Foundation in my tests (I'm not sure if the dependencies will work out for that)?

Also, if you could let me know what errors you got, that would help me out a lot!

gakimball commented 9 years ago

You'd need to compile the Sass files to CSS so that the test browser can see them.

This is the error I get. I think it's happening because the Gulp plugin that generates routes isn't being run, so the foundationRoutes variable is never being created.

Chrome 40.0.2214 (Mac OS X 10.10.1) AboutController should create "phones" model with 3 phones FAILED
    Error: [$injector:modulerr] Failed to instantiate module wxPortal due to:
    Error: [$injector:modulerr] Failed to instantiate module foundation.dynamicRouting due to:
    ReferenceError: foundationRoutes is not defined
mattgrande commented 9 years ago

Ah right, I came across that as well... I'll have to remember what I did to fix that! Thanks for your help.

iotaweb commented 9 years ago

I also encountered this error when trying to run jasmine with a spec runner file. As I didn't want to reference foundation's app.css as it would then override jasmine's styling, I added the following to my specrunner file:

<style>meta.foundation-mq { font-family: "small=&medium=&large=&xlarge=&xxlarge="; }</style>
ghost commented 9 years ago

Is there any quickfix for this issue? I'am using jasmine/karma/phantom.js.

@iotaweb where do you add this line?

tolyo commented 9 years ago

Quickfix for this is to load your css build before your scripts in the karma config file

// list of files / patterns to load in the browser
files: [
        'build/css/app.css',
        'build/js/vendor.js',
        'build/js/app.js',
        'bower_components/angular-mocks/angular-mocks.js',
        'app/**/*.spec.js'
      ],
gakimball commented 9 years ago

If needed, you can also get away with less than that. This is the only line you need:

meta.foundation-mq {
  font-family: "small=0&medium=40rem&large=75rem&xlarge=90rem&xxlarge=120rem"; }

This style could also be added programmatically before Foundation initializes, using the CSSStyleSheet.insertRule() method.

ghost commented 9 years ago

@tolyo @gakimball Thanks a lot. This works for me.

mattgrande commented 9 years ago

@herrreiprich - Where did you end up adding the insertRule call? I've tried a couple places, and it seems to either be too early or too late...

ghost commented 9 years ago

@mattgrande just add it to your Stylesheet and add the file to your Karma conf