2017-02-02 19:56:41 +08:00
/* globals describe, it */
2017-01-07 10:36:33 +08:00
"use strict" ;
2017-02-02 19:56:41 +08:00
require ( "should" ) ;
2017-01-07 10:36:33 +08:00
const webpack = require ( "../lib/webpack" ) ;
const WebpackOptionsValidationError = require ( "../lib/WebpackOptionsValidationError" ) ;
2016-09-19 06:54:35 +08:00
describe ( "Validation" , function ( ) {
2017-01-07 10:36:33 +08:00
const testCases = [ {
2016-09-19 06:54:35 +08:00
name : "undefined configuration" ,
config : undefined ,
message : [
" - configuration should be an object."
]
} , {
name : "null configuration" ,
config : null ,
message : [
" - configuration should be an object."
]
} , {
name : "empty configuration" ,
config : { } ,
message : [
" - configuration misses the property 'entry'." ,
2017-01-09 15:31:49 +08:00
" object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function" ,
2016-09-19 06:54:35 +08:00
" The entry point(s) of the compilation."
]
} , {
name : "empty entry string" ,
config : {
entry : ""
} ,
message : [
" - configuration.entry should be one of these:" ,
2017-01-09 15:31:49 +08:00
" object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function" ,
2016-12-14 18:34:31 +08:00
" The entry point(s) of the compilation." ,
" Details:" ,
" * configuration.entry should be an object." ,
" * configuration.entry should not be empty." ,
" * configuration.entry should be an array:" ,
2017-01-09 15:31:49 +08:00
" [non-empty string]" ,
" * configuration.entry should be an instance of function" ,
" function returning an entry object or a promise.."
2016-09-19 06:54:35 +08:00
]
2017-01-04 13:23:57 +08:00
} , {
name : "empty entry bundle array" ,
config : {
entry : {
"bundle" : [ ]
}
} ,
message : [
" - configuration.entry should be one of these:" ,
2017-01-09 15:31:49 +08:00
" object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function" ,
2017-01-04 13:23:57 +08:00
" The entry point(s) of the compilation." ,
" Details:" ,
" * configuration.entry['bundle'] should be a string." ,
" * configuration.entry['bundle'] should not be empty." ,
" * configuration.entry['bundle'] should be one of these:" ,
" non-empty string | [non-empty string]" ,
" * configuration.entry should be a string." ,
" * configuration.entry should be an array:" ,
2017-01-09 15:31:49 +08:00
" [non-empty string]" ,
" * configuration.entry should be an instance of function" ,
" function returning an entry object or a promise.."
2017-01-04 13:23:57 +08:00
]
2016-11-04 06:52:59 +08:00
} , {
name : "invalid instanceof" ,
config : {
entry : "a" ,
module : {
2016-11-04 07:31:49 +08:00
wrappedContextRegExp : 1337
2016-11-04 06:52:59 +08:00
}
} ,
message : [
2016-11-04 07:31:49 +08:00
" - configuration.module.wrappedContextRegExp should be an instance of RegExp." ,
2016-11-04 06:52:59 +08:00
]
2016-09-19 06:54:35 +08:00
} , {
name : "multiple errors" ,
config : {
entry : [ /a/ ] ,
output : {
filename : /a/
}
} ,
message : [
" - configuration.entry should be one of these:" ,
2017-01-09 15:31:49 +08:00
" object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function" ,
2016-09-19 06:54:35 +08:00
" The entry point(s) of the compilation." ,
2016-12-14 18:34:31 +08:00
" Details:" ,
" * configuration.entry should be an object." ,
" * configuration.entry should be a string." ,
" * configuration.entry[0] should be a string." ,
2017-01-09 15:31:49 +08:00
" * configuration.entry should be an instance of function" ,
" function returning an entry object or a promise.." ,
2016-09-19 06:54:35 +08:00
" - configuration.output.filename should be a string."
]
} , {
name : "multiple configurations" ,
config : [ {
entry : [ /a/ ] ,
} , {
entry : "a" ,
output : {
filename : /a/
}
} ] ,
message : [
" - configuration[0].entry should be one of these:" ,
2017-01-09 15:31:49 +08:00
" object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function" ,
2016-09-19 06:54:35 +08:00
" The entry point(s) of the compilation." ,
2016-12-14 18:34:31 +08:00
" Details:" ,
" * configuration[0].entry should be an object." ,
" * configuration[0].entry should be a string." ,
" * configuration[0].entry[0] should be a string." ,
2017-01-09 15:31:49 +08:00
" * configuration[0].entry should be an instance of function" ,
" function returning an entry object or a promise.." ,
2016-09-19 06:54:35 +08:00
" - configuration[1].output.filename should be a string."
]
} , {
name : "deep error" ,
config : {
entry : "a" ,
module : {
rules : [ {
oneOf : [ {
2017-02-02 19:36:15 +08:00
test : "/a" ,
2016-09-19 06:54:35 +08:00
paser : {
amd : false
}
} ]
} ]
}
} ,
message : [
" - configuration.module.rules[0].oneOf[0] has an unknown property 'paser'. These properties are valid:" ,
2016-11-23 00:58:24 +08:00
" object { enforce?, exclude?, include?, issuer?, loader?, loaders?, oneOf?, options?, parser?, query?, resource?, resourceQuery?, rules?, test?, use? }"
2016-09-19 06:54:35 +08:00
]
2016-09-21 02:18:52 +08:00
} , {
name : "additional key on root" ,
config : {
entry : "a" ,
postcss : function ( ) { }
} ,
message : [
" - configuration has an unknown property 'postcss'. These properties are valid:" ,
2016-09-21 02:29:07 +08:00
" object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry, externals?, " +
2016-11-23 02:11:03 +08:00
"loader?, module?, name?, node?, output?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, " +
2016-09-21 02:54:09 +08:00
"recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }" ,
2016-09-21 02:18:52 +08:00
" For typos: please correct them." ,
" For loader options: webpack 2 no longer allows custom properties in configuration." ,
" Loaders should be updated to allow passing options via loader options in module.rules." ,
" Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:" ,
2016-09-28 18:54:46 +08:00
" plugins: [" ,
2016-09-21 02:18:52 +08:00
" new webpack.LoaderOptionsPlugin({" ,
2016-09-21 23:44:57 +08:00
" // test: /\\.xxx$/, // may apply this only for some modules" ,
2016-09-21 02:18:52 +08:00
" options: {" ,
" postcss: ..." ,
" }" ,
" })" ,
2016-09-28 18:54:46 +08:00
" ]"
2016-09-21 02:18:52 +08:00
]
2016-12-14 19:03:24 +08:00
} , {
name : "enum" ,
config : {
entry : "a" ,
devtool : true
} ,
message : [
" - configuration.devtool should be one of these:" ,
" string | false" ,
" A developer tool to enhance debugging." ,
" Details:" ,
" * configuration.devtool should be a string." ,
" * configuration.devtool should be false"
]
2017-02-03 21:49:38 +08:00
} , {
name : "non-absolute path" ,
config : {
entry : "foo.js" ,
output : {
filename : "/bar"
}
} ,
message : [
" - configuration.output.filename A non-absolut path is expected. However the provided value \"/bar\" is an absolute path!" ,
" ({" ,
" \"keyword\": \"absolutePath\"," ,
" \"params\": {" ,
" \"absolutePath\": \"/bar\"" ,
" }," ,
" \"message\": \"A non-absolut path is expected. However the provided value \\\"/bar\\\" is an absolute path!\\n\"," ,
" \"parentSchema\": {" ,
" \"description\": \"Specifies the name of each output file on disk. You must **not** specify an absolute path here! The `output.path` option determines the location on disk the files are written to, filename is used solely for naming the individual files.\"," ,
" \"type\": \"string\"," ,
" \"absolutePath\": false" ,
" }," ,
" \"dataPath\": \".output.filename\"," ,
" \"schemaPath\": \"#/definitions/output/properties/filename/absolutePath\"," ,
" \"schema\": false," ,
" \"data\": \"/bar\"" ,
" })." ,
" string" ,
" Specifies the name of each output file on disk. You must **not** specify an absolute path here! The `output.path` option determines the location on disk the files are written to, filename is used solely for naming the individual files."
]
} , {
name : "absolute path" ,
config : {
entry : "foo.js" ,
output : {
filename : "bar"
} ,
context : "baz"
} ,
message : [
" - configuration.context The provided value \"baz\" is not an absolute path!" ,
" ({" ,
" \"keyword\": \"absolutePath\"," ,
" \"params\": {" ,
" \"absolutePath\": \"baz\"" ,
" }," ,
" \"message\": \"The provided value \\\"baz\\\" is not an absolute path!\\n\"," ,
" \"parentSchema\": {" ,
" \"description\": \"The base directory (absolute path!) for resolving the `entry` option. If `output.pathinfo` is set, the included pathinfo is shortened to this directory.\"," ,
" \"type\": \"string\"," ,
" \"absolutePath\": true" ,
" }," ,
" \"dataPath\": \".context\"," ,
" \"schemaPath\": \"#/properties/context/absolutePath\"," ,
" \"schema\": true," ,
" \"data\": \"baz\"" ,
" })." ,
" string" ,
" The base directory (absolute path!) for resolving the `entry` option. If `output.pathinfo` is set, the included pathinfo is shortened to this directory."
]
2016-09-19 06:54:35 +08:00
} ] ;
testCases . forEach ( function ( testCase ) {
it ( "should fail validation for " + testCase . name , function ( ) {
try {
webpack ( testCase . config ) ;
} catch ( e ) {
if ( ! ( e instanceof WebpackOptionsValidationError ) )
throw e ;
e . message . should . startWith ( "Invalid configuration object." ) ;
e . message . split ( "\n" ) . slice ( 1 ) . should . be . eql ( testCase . message ) ;
return ;
}
throw new Error ( "Validation didn't fail" ) ;
2017-02-02 19:56:41 +08:00
} ) ;
2016-09-19 06:54:35 +08:00
} ) ;
} ) ;