1
- import ma = require ( './mock-answer' ) ;
2
- import mockery = require ( 'mockery' ) ;
1
+ import { TaskLibAnswers } from './mock-answer' ;
2
+ import { SinonSandbox , createSandbox } from 'sinon' ;
3
3
import im = require( './internal' ) ;
4
+ import * as taskLib from './task' ;
4
5
5
6
export class TaskMockRunner {
6
7
constructor ( taskPath : string ) {
7
8
this . _taskPath = taskPath ;
9
+ this . _sandbox = createSandbox ( ) ;
8
10
}
9
11
10
12
_taskPath : string ;
11
- _answers : ma . TaskLibAnswers | undefined ;
13
+ _answers : TaskLibAnswers | undefined ;
12
14
_exports : { [ key : string ] : any } = { } ;
13
15
_moduleCount : number = 0 ;
16
+ private _sandbox : SinonSandbox ;
14
17
15
18
public setInput ( name : string , val : string ) {
16
19
let key : string = im . _getVariableKey ( name ) ;
@@ -32,10 +35,43 @@ export class TaskMockRunner {
32
35
*
33
36
* @param answers Answers to be returned when the task lib functions are called.
34
37
*/
35
- public setAnswers ( answers : ma . TaskLibAnswers ) {
38
+ public setAnswers ( answers : TaskLibAnswers ) {
36
39
this . _answers = answers ;
37
40
}
38
41
42
+ checkModuleName ( modName : any ) : boolean {
43
+ if ( typeof modName !== 'string' ) {
44
+ return false ;
45
+ }
46
+
47
+ if ( modName . includes ( '.' ) ) {
48
+ console . log ( `WARNING: ${ modName } is a local module. Cannot require it from task-lib. Please pass an already imported module.` ) ;
49
+ return false ;
50
+ }
51
+
52
+ return true ;
53
+ }
54
+
55
+
56
+ checkIsMockable ( newModule , methodName , oldModule ) {
57
+ const method = newModule [ methodName ] ;
58
+
59
+ if ( ! newModule . hasOwnProperty ( methodName ) || typeof method === 'undefined' ) {
60
+ return false ;
61
+ }
62
+
63
+ if ( typeof method !== 'function' ) {
64
+ console . log ( `WARNING: ${ methodName } of ${ newModule } is not a function. There is no option to replace getter/setter in this implementation. You can consider changing it.` ) ;
65
+ return false ;
66
+ }
67
+
68
+ const descriptor = Object . getOwnPropertyDescriptor ( oldModule , methodName ) ;
69
+
70
+ return descriptor && descriptor . writable !== false ;
71
+ }
72
+
73
+
74
+
39
75
/**
40
76
* Register a mock module. When require() is called for the module name,
41
77
* the mock implementation will be returned instead.
@@ -44,9 +80,22 @@ export class TaskMockRunner {
44
80
* @param val Mock implementation of the module.
45
81
* @returns void
46
82
*/
47
- public registerMock ( modName : string , mod : any ) : void {
83
+ public registerMock ( modName : any , mod : any ) : void {
48
84
this . _moduleCount ++ ;
49
- mockery . registerMock ( modName , mod ) ;
85
+ let oldMod : object ;
86
+
87
+ if ( this . checkModuleName ( modName ) ) {
88
+ oldMod = require ( modName ) ;
89
+ } else {
90
+ oldMod = modName ;
91
+ }
92
+
93
+ for ( let method in oldMod ) {
94
+ if ( this . checkIsMockable ( mod , method , oldMod ) ) {
95
+ const replacement = mod [ method ] || oldMod [ method ] ;
96
+ this . _sandbox . replace ( oldMod , method , replacement ) ;
97
+ }
98
+ }
50
99
}
51
100
52
101
/**
@@ -69,11 +118,6 @@ export class TaskMockRunner {
69
118
* @returns void
70
119
*/
71
120
public run ( noMockTask ?: boolean ) : void {
72
- // determine whether to enable mockery
73
- if ( ! noMockTask || this . _moduleCount ) {
74
- mockery . enable ( { warnOnUnregistered : false } ) ;
75
- }
76
-
77
121
// answers and exports not compatible with "noMockTask" mode
78
122
if ( noMockTask ) {
79
123
if ( this . _answers || Object . keys ( this . _exports ) . length ) {
@@ -92,10 +136,21 @@ export class TaskMockRunner {
92
136
tlm [ key ] = this . _exports [ key ] ;
93
137
} ) ;
94
138
95
- mockery . registerMock ( 'azure-pipelines-task-lib/task' , tlm ) ;
139
+
140
+ var tlt = require ( 'azure-pipelines-task-lib/task' ) ;
141
+ for ( let method in tlt ) {
142
+ if ( tlm . hasOwnProperty ( method ) ) {
143
+ this . _sandbox . replace ( tlt , method , tlm [ method ] ) ;
144
+ }
145
+ }
146
+
96
147
}
97
148
98
149
// run it
99
150
require ( this . _taskPath ) ;
100
151
}
152
+
153
+ public restore ( ) {
154
+ this . _sandbox . restore ( ) ;
155
+ }
101
156
}
0 commit comments