1 | path = require "path"
|
2 | resolve = require "resolve"
|
3 | fs = require "fs"
|
4 | rewire = require "rewire"
|
5 | _ = require "lodash"
|
6 | esprima = require "esprima"
|
7 | mock = require "./mock"
|
8 |
|
9 |
|
10 | set = (wired, path, value) -> wired.__set__ path, value
|
11 |
|
12 | get = (wired, path) -> wired.__get__ path
|
13 |
|
14 | if_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 |
|
32 | if_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 |
|
51 | internal_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 |
|
63 | abs_path = (loc, base) ->
|
64 | resolve.sync loc, basedir: base || ""
|
65 |
|
66 | each_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 |
|
79 | matches_module = (mod, base) -> (compare) -> compare is mod.path
|
80 |
|
81 | parse_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 |
|
95 | load = (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 |
|
101 | module.exports =
|
102 | set: set
|
103 | get: get
|
104 | load: load
|