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 |
|
18 | fs = require 'fs'
|
19 | {sep} = require 'path'
|
20 |
|
21 | module.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 |
|
57 | override = {} # override list
|
58 | lstatOverride = {} # paths that 'fake exist'
|
59 | activated = false
|
60 |
|
61 | Object.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
|