UNPKG

4.91 kBtext/coffeescriptView Raw
1
2
3#
4# HAC
5# ===
6#
7# ipso.define(list)
8# -----------------
9#
10# creates capacity to return mock module using require
11#
12# Achieved by tailoring the behaviours of fs{readFileSync, statSync, lstatSync}
13# such that when they are called from require('module-name') (module.js) they
14# return faked responses that create the appearence of the module being installed.
15#
16#
17
18fs = require 'fs'
19{sep} = require 'path'
20
21module.exports = (list) ->
22
23 module.exports.activate()
24
25 for moduleName of list
26
27 type = 'literal'
28 name = moduleName
29
30 override[name] =
31
32 type: type
33
34 'package.json':
35 name: name
36 version: '0.0.0'
37 main: 'STUBBED.js'
38 dependencies: {}
39
40 'STUBBED.js':
41 list[moduleName]
42
43 #
44 # immediately do the first require to create the mock
45 # subclasses ""as mocks""
46 #
47 # this alleviates the problem of the first injection of
48 # the mock being perfomed ahead of the require, leading
49 # to the submodules being created as ""PENDING modules""
50 # instead of mocks (ie. define $save)
51 #
52
53 if type is 'literal' then require name
54
55
56
57override = {} # override list
58lstatOverride = {} # paths that 'fake exist'
59activated = false
60
61Object.defineProperty module.exports, 'activate', enumarable: 'false', get: ->
62
63 if activated then return ->
64 return ->
65
66 activated = true
67 readFileSync = fs.readFileSync
68 fs.readFileSync = (path, encoding) ->
69
70 ### MODIFIED BY ipso.define ###
71
72 [mod, file] = path.split( sep )[-2..]
73 parts = path.split( sep )[0..-3]
74
75 modulesPath = parts.join sep
76 modulePath = parts.concat([mod]).join sep
77 scriptPath = parts.concat([mod, 'STUBBED.js']).join sep
78
79 #
80 # dodge modules with names that are properties of Object
81 #
82
83 # ignore = [
84 # 'should'
85 # ]
86
87 if override.hasOwnProperty(mod) # and ignore.indexOf( mod ) < 0
88
89 type = override[mod].type
90
91 switch file
92
93 when 'package.json'
94
95 lstatOverride[modulesPath] = 1
96 lstatOverride[modulePath] = 1
97 lstatOverride[scriptPath] = 1
98
99 return JSON.stringify override[mod]['package.json']
100
101
102 when 'STUBBED.js'
103
104 if typeof override[mod]['STUBBED.js'] is 'function'
105
106 if override[mod].scriptPath?
107
108 #
109 # Same module has already been required and
110 # a different path was resolved,
111 #
112 # Proxy require to the original path to preserve
113 # require cache.
114 #
115
116 return """
117 module.exports = require('#{override[mod].scriptPath}');
118 """
119
120 else
121
122 override[mod].scriptPath = scriptPath
123
124 return """
125
126 ipso = require('ipso'); // testing catch 22
127 mock = ipso.mock;
128 Mock = ipso.Mock;
129 get = function(tag) {
130
131 try { return ipso.does.getSync(tag).object }
132 catch (error) { console.log('ipso: missing mock "%s"', tag); }
133
134 };
135
136 module.exports = #{
137
138 switch type
139
140 when 'literal'
141
142 "(#{override[mod]['STUBBED.js'].toString()}).call(this);"
143
144 }
145 """
146
147 else
148
149 console.log """
150 ipso.define(list) requires list of functions to be exported as modules,
151 or used as module factories.
152 """.red
153
154
155
156
157 readFileSync path, encoding
158
159 statSync = fs.statSync
160 fs.statSync = (path) ->
161
162 ### MODIFIED BY ipso.define ###
163
164 if path.match /STUBBED.js/ then return {
165 isDirectory: -> false
166 }
167
168 statSync path
169
170
171 lstatSync = fs.lstatSync
172 fs.lstatSync = (path) ->
173
174 ### MODIFIED BY ipso.define ###
175
176 if lstatOverride[path]? then return {
177 isSymbolicLink: -> false
178 }
179
180 lstatSync path