@@ -7,6 +7,8 @@ var gulp = require('gulp'),
7
7
querystring = require ( 'querystring' ) ,
8
8
childProcess = require ( 'child_process' ) ;
9
9
10
+ var yargs = require ( '../util/yargs' ) ;
11
+
10
12
/**
11
13
* Wrap the given value in quotation marks
12
14
* @param {* } value The value to wrap
@@ -16,7 +18,73 @@ function quote(value) {
16
18
return '"' + value + '"' ;
17
19
}
18
20
21
+ var defaultReporterName = 'angularity-karma-reporter' ;
22
+
19
23
var filesAppendRegex = / \/ \* + \s * A N G U L A R I T Y _ F I L E _ L I S T \s * \* + \/ / ;
24
+ var reportersAppendRegex = / \/ \* + \s * A N G U L A R I T Y _ R E P O R T E R _ L I S T \s * \* + \/ / ;
25
+ var pluginsAppendRegex = / \/ \* + \s * A N G U L A R I T Y _ P L U G I N _ L I S T \s * \* + \/ / ;
26
+ var karmaReporterMatchNameRegex = / ^ k a r m a - ( .+ ) - r e p o r t e r $ / ;
27
+
28
+ /**
29
+ * Determine the `require` path for a plugin.
30
+ *
31
+ * @param {string } reporterName Either a package name,
32
+ * *OR* an absolute path, for a karma reporter.
33
+ * @return {string } In karma config file, `plugins` will be inline `require`d
34
+ * using this return value.
35
+ */
36
+ function getKarmaReporterPluginPath ( reporterName ) {
37
+ if ( typeof reporterName !== 'string' ) {
38
+ throw 'Get Karma Reporter Plugin Path: Reporter name is unspecified' ;
39
+ }
40
+
41
+ if ( reporterName === defaultReporterName ) {
42
+ return defaultReporterName ;
43
+ }
44
+ else {
45
+ var reporterPath = ( path . dirname ( reporterName ) === '.' ) ?
46
+ path . resolve ( 'node_modules' , 'karma-' + reporterName + '-reporter' ) :
47
+ reporterName ;
48
+ try {
49
+ require ( reporterPath ) ;
50
+ }
51
+ catch ( ex ) {
52
+ throw 'Get Karma Reporter Plugin Path: Attempt to require reporter from path ' +
53
+ reporterPath + ' with no success.' ;
54
+ }
55
+ reporterPath = path . normalize ( reporterPath ) ;
56
+ //quirk: nodejs identifies all windows (both win32 and win64) as win32
57
+ if ( process . platform === 'win32' ) {
58
+ //replace any single backslash characters in file paths with
59
+ //double backslash on windows; neither path.normalize nor path.resolve do this
60
+ reporterPath = reporterPath . replace ( / \\ / g , '\\\\' ) ;
61
+ }
62
+ return reporterPath ;
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Determine the registered reporter name.
68
+ *
69
+ * @param {string } reporterName Either the registered reporter name,
70
+ * *OR* an absolute path, for a karma reporter.
71
+ * @return {string } The registered reporter name for use in
72
+ * the `reporters` section of the karma config file.
73
+ */
74
+ function getKarmaReporterName ( reporterName ) {
75
+ if ( typeof reporterName !== 'string' ) {
76
+ throw 'Get Karma Reporter Name: Reporter name is unspecified' ;
77
+ }
78
+
79
+ var name = ( path . dirname ( reporterName ) === '.' ) ?
80
+ reporterName :
81
+ path . basename ( reporterName ) ;
82
+ var match = karmaReporterMatchNameRegex . exec ( name ) ;
83
+ if ( ! ! match && match . length === 2 ) {
84
+ name = match [ 1 ] ;
85
+ }
86
+ return name
87
+ }
20
88
21
89
/**
22
90
* Create a through2 object stream.
@@ -27,13 +95,15 @@ var filesAppendRegex = /\/\*+\s*ANGULARITY_FILE_LIST\s*\*+\// ;
27
95
* The new karma config file is added to the stream,
28
96
* All input `*.js` files are filtered out of the stream
29
97
*
30
- * @param {string } configFileName The project local karma config file to augment
98
+ * @param {Array.<string> } [reporters] The name of the karma reporter to use
99
+ * @param {string } [configFileName] The project local karma config file to augment
31
100
* Defaults to "karma.conf.js"
32
101
* @return {stream.Through } The output of this stream is expected to contain
33
102
* just one file: the augmented karma config file.
34
103
*/
35
- function karmaCreateConfig ( configFileName ) {
36
- configFileName = 'karma.conf.js' ;
104
+ function karmaCreateConfig ( reporters , configFileName ) {
105
+ reporters = reporters || [ ] ;
106
+ configFileName = configFileName || 'karma.conf.js' ;
37
107
var files = [ ] ;
38
108
39
109
function transformFn ( file , encoding , done ) {
@@ -47,13 +117,20 @@ function karmaCreateConfig(configFileName) {
47
117
function flushFn ( done ) {
48
118
var stream = this ;
49
119
var filesAppend = JSON . stringify ( files , null , ' ' ) ;
120
+ var reportersAppend = JSON . stringify ( reporters . map ( getKarmaReporterName ) , null , ' ' ) ;
121
+ var pluginsAppend = '[\n' + reporters . map ( function ( reporter ) {
122
+ return 'require("' + getKarmaReporterPluginPath ( reporter ) + '")' ;
123
+ } ) . join ( ',\n ' ) + '\n]' ;
50
124
51
125
//aggregate and append to karma.conf.js in the project root folder
52
126
gulp
53
127
. src ( path . resolve ( configFileName ) )
54
128
. on ( 'data' , function ( karmaConfigFile ) {
55
- var contents = karmaConfigFile . contents . toString ( ) ;
56
- contents = contents . replace ( filesAppendRegex , filesAppend ) ;
129
+ var contents = karmaConfigFile . contents . toString ( )
130
+ . replace ( filesAppendRegex , filesAppend )
131
+ . replace ( reportersAppendRegex , reportersAppend )
132
+ . replace ( reportersAppendRegex , reportersAppend )
133
+ . replace ( pluginsAppendRegex , pluginsAppend ) ;
57
134
karmaConfigFile . contents = new Buffer ( contents ) ;
58
135
stream . push ( karmaConfigFile ) ;
59
136
} )
@@ -70,13 +147,15 @@ function karmaCreateConfig(configFileName) {
70
147
* No output. Ends when the Karma process ends.
71
148
* Runs karma in a child process, to avoid `process.exit()` called by karma.
72
149
*
150
+ * @param {Array.<string> } [reporters] The name of the karma reporter to use
73
151
* @param {number } [bannerWidth] The width of banner comment, zero or omitted for none
74
152
* @returns {stream.Through } A through strconcateam that performs the operation of a gulp stream
75
153
*/
76
- function karmaRun ( bannerWidth ) {
154
+ function karmaRun ( reporters , bannerWidth ) {
77
155
var options = {
78
156
configFile : undefined
79
157
} ;
158
+ reporters = reporters || [ ] ;
80
159
81
160
return through . obj ( function transformFn ( file , encoding , done ) {
82
161
options . configFile = file . path ;
@@ -87,23 +166,32 @@ function karmaRun(bannerWidth) {
87
166
var data = querystring . escape ( JSON . stringify ( options ) ) ;
88
167
var command = [ 'node' , quote ( appPath ) , data ] . join ( ' ' ) ;
89
168
90
- //TODO @bguiz replace reporter function with a standard karma reporter,
91
- //and extract it to own module
92
- //perhaps extend the spec reporter to do what is being done here, instead of post processing its output here
93
- //check if there is a webstorm/ teamcity reporter
94
169
childProcess . exec ( command , { cwd : process . cwd ( ) } , function reporter ( stderr , stdout ) {
170
+ if ( reporters . length > 0 ) {
171
+ if ( stdout ) {
172
+ process . stdout . write ( stdout ) ;
173
+ }
174
+ if ( stderr ) {
175
+ process . stderr . write ( stderr ) ;
176
+ }
177
+ done ( ) ;
178
+ return ;
179
+ }
180
+
181
+ //TODO @bguiz replace reporter function with a standard karma reporter,
182
+ //and extract it to own module
183
+
184
+ //default reporter by parsing the stdout and stderr of karma
95
185
var report ;
96
186
if ( stdout ) {
97
- console . log ( stdout ) ;
98
187
report = stdout
99
188
. replace ( / ^ \s + / gm, '' ) // remove leading whitespace
100
189
. replace ( / ^ ( L O G .* \n $ ) / gm, options . silent ? '' : '$1' ) // remove logging
101
190
. replace ( / a t \s + n u l l \. .* / gm, '' ) // remove file reference
102
191
. replace ( / \n \n / gm, '\n' ) // consolidate consecutive line breaks
103
192
. replace ( / ^ \n | \n $ / g, '' ) ; // remove leading and trailing line breaks overall
104
- } else if ( stderr ) {
105
- console . log ( stderr ) ;
106
-
193
+ }
194
+ else if ( stderr ) {
107
195
var analysis = / $ E r r o r \: \s * ( .* ) $ / mg. exec ( stderr ) ;
108
196
report = analysis ? analysis [ 1 ] : stderr ;
109
197
}
@@ -119,7 +207,37 @@ function karmaRun(bannerWidth) {
119
207
} ) ;
120
208
} ;
121
209
210
+ var yargsOptionDefiniton = {
211
+ key : 'karmareporter' ,
212
+ value : {
213
+ describe : 'Specify a custom Karma reporter to use. ' +
214
+ 'Either a locally npm installed module, or an asolute path to one.' ,
215
+ alias : [ 'k' ] ,
216
+ default : defaultReporterName ,
217
+ string :true ,
218
+ }
219
+ } ;
220
+ var checkKarmaReporter = yargs . createCheck ( )
221
+ . withGate ( function ( argv ) {
222
+ return ! argv . help ;
223
+ } )
224
+ . withTest ( {
225
+ karmareporter : function ( value ) {
226
+ if ( typeof value !== 'undefined' ) {
227
+ try {
228
+ getKarmaReporterPluginPath ( value ) ;
229
+ }
230
+ catch ( ex ) {
231
+ return 'Illegal value for "reporter"\n' + ex ;
232
+ }
233
+ }
234
+ } ,
235
+ } )
236
+ . commit ( ) ;
237
+
122
238
module . exports = {
123
239
createConfig : karmaCreateConfig ,
124
- run : karmaRun
240
+ run : karmaRun ,
241
+ yargsCheck : checkKarmaReporter ,
242
+ yargsOption : yargsOptionDefiniton ,
125
243
} ;
0 commit comments