UNPKG

2.8 kBtext/coffeescriptView Raw
1path = require "path"
2resolve = require "resolve"
3fs = require "fs"
4rewire = require "rewire"
5_ = require "lodash"
6esprima = require "esprima"
7mock = require "./mock"
8
9# can use revert for part of undo = myModule.__set__(...)
10set = (wired, path, value) -> wired.__set__ path, value
11
12get = (wired, path) -> wired.__get__ path
13
14if_variable_declaration = (node, base, list) ->
15 return if !node || node.type != "VariableDeclaration"
16
17 _.each node.declarations, (declare) ->
18 statement = declare &&
19 declare.type == "VariableDeclarator" &&
20 declare.init
21
22 return if not statement
23
24 if statement.callee && statement.callee.name == "require"
25 statement_args = statement.arguments && statement.arguments.length > 0
26 mod_loc = if statement_args then statement.arguments[0].value
27
28 list.push
29 name: if declare.id then declare.id.name
30 path: mod_loc
31
32if_assignment_statement = (node, base, list) ->
33 exp = node && node.type == "ExpressionStatement" && node.expression
34
35 if exp.type == "AssignmentExpression" &&
36 exp.right && exp.left &&
37 exp.right.type == "CallExpression" &&
38 exp.right.callee.name == "require"
39
40 name = switch
41 when exp.left.type == "Identifier" then exp.left.name
42 else name = exp.left.object.name + "." + exp.left.property.name
43
44 right_args = exp.right.arguments && exp.right.arguments.length > 0
45 mod_loc = if right_args then exp.right.arguments[0].value
46
47 list.push
48 name: name
49 path: mod_loc
50
51internal_modules = (ast, base, list) ->
52 list = [] unless list
53
54 return list if not ast or not ast.body
55
56 _.each ast.body, (node) ->
57 if_variable_declaration node, base, list
58 if_assignment_statement node, base, list
59 internal_modules node, base, list
60
61 list
62
63abs_path = (loc, base) ->
64 resolve.sync loc, basedir: base || ""
65
66each_sub_mod = (file) ->
67 base = path.dirname file
68 mods = null
69
70 if fs.existsSync file
71 data = fs.readFileSync file, "utf-8"
72
73 if data
74 ast = esprima.parse data
75 mods = internal_modules ast, base
76
77 mods || []
78
79matches_module = (mod, base) -> (compare) -> compare is mod.path
80
81parse_private_modules = (module_path, wired, accept) ->
82 each_sub_mod module_path
83 .forEach (mod) ->
84 return unless accept.some matches_module mod, module_path
85
86 obj = get wired, mod.name
87
88 _.each Object.keys(obj), (key) ->
89 return unless typeof obj[key] is "function"
90 obj[key] = mock.stub obj, key
91
92 if typeof obj == "function"
93 set wired, mod.name, _.extend mock.stub(), obj
94
95load = (module_path, base, accept=[]) ->
96 full_path = abs_path module_path, base
97 wired = rewire full_path
98 parse_private_modules full_path, wired, accept
99 wired
100
101module.exports =
102 set: set
103 get: get
104 load: load