Skip to content

Commit

Permalink
feat(middleware): added manual file type option
Browse files Browse the repository at this point in the history
Adds a manual file type so that users can instruct Karma which method to use when loading a file without an extension (such as Google font files) or others like ES modules.

Closes #2824
  • Loading branch information
josh18 authored and dignifiedquire committed Nov 21, 2017
1 parent b8a750a commit 0330cd1
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 19 deletions.
11 changes: 11 additions & 0 deletions docs/config/02-files.md
Expand Up @@ -24,6 +24,17 @@ Each pattern is either a simple string or an object with four properties:
* **No Default.**
* **Description.** The pattern to use for matching. This property is mandatory.

### `type`
* **Type.** String
* **Default.** Will attempt to determine type based on file extension. If that fails, defaults to `js`.
* **Description.** Choose the type to use when including a file.
* **Possible Values:**
* `css`
* `html`
* `js`
* `dart`
* `module`

### `watched`
* **Type.** Boolean
* **Default.** `true`
Expand Down
6 changes: 4 additions & 2 deletions lib/config.js
Expand Up @@ -36,13 +36,14 @@ try {
TYPE_SCRIPT_AVAILABLE = true
} catch (e) {}

var Pattern = function (pattern, served, included, watched, nocache) {
var Pattern = function (pattern, served, included, watched, nocache, type) {
this.pattern = pattern
this.served = helper.isDefined(served) ? served : true
this.included = helper.isDefined(included) ? included : true
this.watched = helper.isDefined(watched) ? watched : true
this.nocache = helper.isDefined(nocache) ? nocache : false
this.weight = helper.mmPatternWeight(pattern)
this.type = type
}

Pattern.prototype.compare = function (other) {
Expand All @@ -67,7 +68,8 @@ var createPatternObject = function (pattern) {
pattern.served,
pattern.included,
pattern.watched,
pattern.nocache)
pattern.nocache,
pattern.type)
}

log.warn('Invalid pattern %s!\n\tObject is missing "pattern" property.', pattern)
Expand Down
3 changes: 2 additions & 1 deletion lib/file-list.js
Expand Up @@ -184,7 +184,8 @@ List.prototype._refresh = function () {

var mtime = mg.statCache[path].mtime
var doNotCache = patternObject.nocache
var file = new File(path, mtime, doNotCache)
var type = patternObject.type
var file = new File(path, mtime, doNotCache, type)

if (file.doNotCache) {
log.debug('Not preprocessing "%s" due to nocache')
Expand Down
4 changes: 3 additions & 1 deletion lib/file.js
Expand Up @@ -9,7 +9,7 @@
var _ = require('lodash')

// Constructor
var File = function (path, mtime, doNotCache) {
var File = function (path, mtime, doNotCache, type) {
// used for serving (processed path, eg some/file.coffee -> some/file.coffee.js)
this.path = path

Expand All @@ -23,6 +23,8 @@ var File = function (path, mtime, doNotCache) {
this.isUrl = false

this.doNotCache = _.isUndefined(doNotCache) ? false : doNotCache

this.type = type
}

File.prototype.toString = function () {
Expand Down
25 changes: 20 additions & 5 deletions lib/middleware/karma.js
Expand Up @@ -15,6 +15,7 @@ var path = require('path')
var util = require('util')
var url = require('url')
var useragent = require('useragent')
var _ = require('lodash')

var log = require('../logger').create('middleware:karma')

Expand All @@ -32,9 +33,17 @@ var CROSSORIGIN_ATTRIBUTE = 'crossorigin="anonymous"'
var LINK_TAG_CSS = '<link type="text/css" href="%s" rel="stylesheet">'
var LINK_TAG_HTML = '<link href="%s" rel="import">'
var SCRIPT_TYPE = {
'.js': 'text/javascript',
'.dart': 'application/dart'
'js': 'text/javascript',
'dart': 'application/dart',
'module': 'module'
}
var FILE_TYPES = [
'css',
'html',
'js',
'dart',
'module'
]

var filePathToUrlPath = function (filePath, basePath, urlRoot, proxyPath) {
if (filePath.indexOf(basePath) === 0) {
Expand Down Expand Up @@ -178,11 +187,16 @@ var createKarmaMiddleware = function (
var file = files.included[i]
var filePath = file.path
var fileExt = path.extname(filePath)
var fileType = file.type

if (!files.included.hasOwnProperty(i)) {
continue
}

if (!_.isUndefined(fileType) && FILE_TYPES.indexOf(fileType) === -1) {
log.warn('Invalid file type, defaulting to js.', fileType)
}

if (!file.isUrl) {
filePath = filePathToUrlPath(filePath, basePath, urlRoot, proxyPath)

Expand All @@ -193,18 +207,19 @@ var createKarmaMiddleware = function (

scriptUrls.push(filePath)

if (fileExt === '.css') {
if (fileType === 'css' || (!fileType && fileExt === '.css')) {
scriptTags.push(util.format(LINK_TAG_CSS, filePath))
continue
}

if (fileExt === '.html') {
if (fileType === 'html' || (!fileType && fileExt === '.html')) {
scriptTags.push(util.format(LINK_TAG_HTML, filePath))
continue
}

// The script tag to be placed
var scriptType = (SCRIPT_TYPE[fileExt] || 'text/javascript')
var scriptFileType = (fileType || fileExt.substring(1))
var scriptType = (SCRIPT_TYPE[scriptFileType] || 'text/javascript')

// In case there is a JavaScript version specified and this is a Firefox browser
if (jsVersion && jsVersion > 0 && isFirefox(request)) {
Expand Down
38 changes: 28 additions & 10 deletions test/unit/middleware/karma.spec.js
Expand Up @@ -13,8 +13,8 @@ describe('middleware.karma', () => {
var nextSpy
var response

var MockFile = function (path, sha) {
File.call(this, path)
var MockFile = function (path, sha, type) {
File.call(this, path, undefined, undefined, type)
this.sha = sha || 'sha-default'
}

Expand Down Expand Up @@ -212,12 +212,14 @@ describe('middleware.karma', () => {
it('should serve context.html with replaced link tags', (done) => {
includedFiles([
new MockFile('/first.css', 'sha007'),
new MockFile('/second.html', 'sha678')
new MockFile('/second.html', 'sha678'),
new MockFile('/third', 'sha111', 'css'),
new MockFile('/fourth', 'sha222', 'html')
])

response.once('end', () => {
expect(nextSpy).not.to.have.been.called
expect(response).to.beServedAs(200, 'CONTEXT\n<link type="text/css" href="/__proxy__/__karma__/absolute/first.css?sha007" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/second.html?sha678" rel="import">')
expect(response).to.beServedAs(200, 'CONTEXT\n<link type="text/css" href="/__proxy__/__karma__/absolute/first.css?sha007" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/second.html?sha678" rel="import">\n<link type="text/css" href="/__proxy__/__karma__/absolute/third?sha111" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/fourth?sha222" rel="import">')
done()
})

Expand All @@ -244,12 +246,16 @@ describe('middleware.karma', () => {
new MockFile('/some/abc/a.css', 'sha1'),
new MockFile('/base/path/b.css', 'sha2'),
new MockFile('/some/abc/c.html', 'sha3'),
new MockFile('/base/path/d.html', 'sha4')
new MockFile('/base/path/d.html', 'sha4'),
new MockFile('/some/abc/e', 'sha5', 'css'),
new MockFile('/base/path/f', 'sha6', 'css'),
new MockFile('/some/abc/g', 'sha7', 'html'),
new MockFile('/base/path/h', 'sha8', 'html')
])

response.once('end', () => {
expect(nextSpy).not.to.have.been.called
expect(response).to.beServedAs(200, 'CONTEXT\n<link type="text/css" href="/__proxy__/__karma__/absolute/some/abc/a.css?sha1" rel="stylesheet">\n<link type="text/css" href="/__proxy__/__karma__/base/b.css?sha2" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/some/abc/c.html?sha3" rel="import">\n<link href="/__proxy__/__karma__/base/d.html?sha4" rel="import">')
expect(response).to.beServedAs(200, 'CONTEXT\n<link type="text/css" href="/__proxy__/__karma__/absolute/some/abc/a.css?sha1" rel="stylesheet">\n<link type="text/css" href="/__proxy__/__karma__/base/b.css?sha2" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/some/abc/c.html?sha3" rel="import">\n<link href="/__proxy__/__karma__/base/d.html?sha4" rel="import">\n<link type="text/css" href="/__proxy__/__karma__/absolute/some/abc/e?sha5" rel="stylesheet">\n<link type="text/css" href="/__proxy__/__karma__/base/f?sha6" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/some/abc/g?sha7" rel="import">\n<link href="/__proxy__/__karma__/base/h?sha8" rel="import">')
done()
})

Expand All @@ -261,7 +267,11 @@ describe('middleware.karma', () => {
new MockFile('/some/abc/a.css', 'sha1'),
new MockFile('/base/path/b.css', 'sha2'),
new MockFile('/some/abc/c.html', 'sha3'),
new MockFile('/base/path/d.html', 'sha4')
new MockFile('/base/path/d.html', 'sha4'),
new MockFile('/some/abc/e', 'sha5', 'css'),
new MockFile('/base/path/f', 'sha6', 'css'),
new MockFile('/some/abc/g', 'sha7', 'html'),
new MockFile('/base/path/h', 'sha8', 'html')
])

response.once('end', () => {
Expand All @@ -271,7 +281,11 @@ describe('middleware.karma', () => {
'/__proxy__/__karma__/absolute/some/abc/a.css?sha1',
'/__proxy__/__karma__/base/b.css?sha2',
'/__proxy__/__karma__/absolute/some/abc/c.html?sha3',
'/__proxy__/__karma__/base/d.html?sha4'
'/__proxy__/__karma__/base/d.html?sha4',
'/__proxy__/__karma__/absolute/some/abc/e?sha5',
'/__proxy__/__karma__/base/f?sha6',
'/__proxy__/__karma__/absolute/some/abc/g?sha7',
'/__proxy__/__karma__/base/h?sha8'
]
}))
done()
Expand Down Expand Up @@ -361,12 +375,16 @@ describe('middleware.karma', () => {
new MockFile('/first.css'),
new MockFile('/base/path/b.css'),
new MockFile('/second.html'),
new MockFile('/base/path/d.html')
new MockFile('/base/path/d.html'),
new MockFile('/third', null, 'css'),
new MockFile('/base/path/f', null, 'css'),
new MockFile('/fourth', null, 'html'),
new MockFile('/base/path/g', null, 'html')
])

response.once('end', () => {
expect(nextSpy).not.to.have.been.called
expect(response).to.beServedAs(200, 'DEBUG\n<link type="text/css" href="/__proxy__/__karma__/absolute/first.css" rel="stylesheet">\n<link type="text/css" href="/__proxy__/__karma__/base/b.css" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/second.html" rel="import">\n<link href="/__proxy__/__karma__/base/d.html" rel="import">')
expect(response).to.beServedAs(200, 'DEBUG\n<link type="text/css" href="/__proxy__/__karma__/absolute/first.css" rel="stylesheet">\n<link type="text/css" href="/__proxy__/__karma__/base/b.css" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/second.html" rel="import">\n<link href="/__proxy__/__karma__/base/d.html" rel="import">\n<link type="text/css" href="/__proxy__/__karma__/absolute/third" rel="stylesheet">\n<link type="text/css" href="/__proxy__/__karma__/base/f" rel="stylesheet">\n<link href="/__proxy__/__karma__/absolute/fourth" rel="import">\n<link href="/__proxy__/__karma__/base/g" rel="import">')
done()
})

Expand Down

0 comments on commit 0330cd1

Please sign in to comment.