1 | var Random = require('./random'),
|
2 | Util = require('./util');
|
3 |
|
4 | var Mock = module.exports = {
|
5 | _mocked: {}
|
6 | };
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 | var rkey = /(.+)\|(?:\+(\d+)|([\+\-]?\d+-?[\+\-]?\d*)?(?:\.(\d+-?\d*))?)/,
|
31 | rrange = /([\+\-]?\d+)-?([\+\-]?\d+)?/,
|
32 | rplaceholder = /\\*@([^@#%&()\?\s\/\.]+)(?:\((.*?)\))?/g;
|
33 |
|
34 | Mock.extend = Util.extend
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | Mock.mock = function(rurl, rtype, template) {
|
50 |
|
51 | if (arguments.length === 1) {
|
52 | return Handle.gen(rurl)
|
53 | }
|
54 |
|
55 | if (arguments.length === 2) {
|
56 | template = rtype
|
57 | rtype = undefined
|
58 | }
|
59 | Mock._mocked[rurl + (rtype || '')] = {
|
60 | rurl: rurl,
|
61 | rtype: rtype,
|
62 | template: template
|
63 | }
|
64 | return Mock
|
65 | }
|
66 |
|
67 | var Handle = {
|
68 | extend: Util.extend
|
69 | }
|
70 |
|
71 | Handle.rule = function(name) {
|
72 | name = (name || '') + ''
|
73 |
|
74 | var parameters = (name || '').match(rkey),
|
75 |
|
76 | range = parameters && parameters[3] && parameters[3].match(rrange),
|
77 | min = range && parseInt(range[1], 10),
|
78 | max = range && parseInt(range[2], 10),
|
79 |
|
80 | count = range ? !range[2] && parseInt(range[1], 10) || Random.integer(min, max) : 1,
|
81 |
|
82 | decimal = parameters && parameters[4] && parameters[4].match(rrange),
|
83 | dmin = decimal && parseInt(decimal[1], 10),
|
84 | dmax = decimal && parseInt(decimal[2], 10),
|
85 |
|
86 | dcount = decimal ? !decimal[2] && parseInt(decimal[1], 10) || Random.integer(dmin, dmax) : 0,
|
87 |
|
88 | point = parameters && parameters[4];
|
89 |
|
90 | return {
|
91 | parameters: parameters,
|
92 | range: range,
|
93 | min: min,
|
94 | max: max,
|
95 | count: count,
|
96 | decimal: decimal,
|
97 | dmin: dmin,
|
98 | dmax: dmax,
|
99 | dcount: dcount,
|
100 | point: point
|
101 | }
|
102 | }
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | Handle.gen = function(template, name, context) {
|
117 | name = name = (name || '') + ''
|
118 |
|
119 | context = context || {}
|
120 | context = {
|
121 |
|
122 | path: context.path || [],
|
123 | templatePath: context.templatePath || [],
|
124 |
|
125 | currentContext: context.currentContext,
|
126 |
|
127 | templateCurrentContext: context.templateCurrentContext || template,
|
128 | root: context.root,
|
129 | templateRoot: context.templateRoot
|
130 | }
|
131 |
|
132 |
|
133 | var rule = Handle.rule(name)
|
134 | var type = Util.type(template)
|
135 |
|
136 | if (Handle[type]) {
|
137 | return Handle[type]({
|
138 |
|
139 | type: type,
|
140 |
|
141 | template: template,
|
142 |
|
143 | name: name,
|
144 |
|
145 | parsedName: name ? name.replace(rkey, '$1') : name,
|
146 |
|
147 |
|
148 | rule: rule,
|
149 |
|
150 | context: context
|
151 | })
|
152 | }
|
153 | return template
|
154 | }
|
155 |
|
156 | Handle.extend({
|
157 | array: function(options) {
|
158 | var result = [],
|
159 | i, j;
|
160 |
|
161 | if (!options.rule.parameters) {
|
162 | for (i = 0; i < options.template.length; i++) {
|
163 | options.context.path.push(i)
|
164 | result.push(
|
165 | Handle.gen(options.template[i], i, {
|
166 | currentContext: result,
|
167 | templateCurrentContext: options.template,
|
168 | path: options.context.path
|
169 | })
|
170 | )
|
171 | options.context.path.pop()
|
172 | }
|
173 | } else {
|
174 |
|
175 | if (options.rule.count === 1 && options.template.length > 1) {
|
176 |
|
177 | options.context.path.push(options.name)
|
178 | result = Random.pick(Handle.gen(options.template, undefined, {
|
179 | currentContext: result,
|
180 | templateCurrentContext: options.template,
|
181 | path: options.context.path
|
182 | }))
|
183 | options.context.path.pop()
|
184 | } else {
|
185 |
|
186 | for (i = 0; i < options.rule.count; i++) {
|
187 |
|
188 | j = 0
|
189 | do {
|
190 |
|
191 | result.push(Handle.gen(options.template[j++]))
|
192 | } while (j < options.template.length)
|
193 | }
|
194 | }
|
195 | }
|
196 | return result
|
197 | },
|
198 | object: function(options) {
|
199 | var result = {},
|
200 | keys, fnKeys, key, parsedKey, inc, i;
|
201 |
|
202 |
|
203 | if (options.rule.min) {
|
204 | keys = Util.keys(options.template)
|
205 | keys = Random.shuffle(keys)
|
206 | keys = keys.slice(0, options.rule.count)
|
207 | for (i = 0; i < keys.length; i++) {
|
208 | key = keys[i]
|
209 | parsedKey = key.replace(rkey, '$1')
|
210 | options.context.path.push(parsedKey)
|
211 | result[parsedKey] = Handle.gen(options.template[key], key, {
|
212 | currentContext: result,
|
213 | templateCurrentContext: options.template,
|
214 | path: options.context.path
|
215 | })
|
216 | options.context.path.pop()
|
217 | }
|
218 |
|
219 | } else {
|
220 |
|
221 | keys = []
|
222 | fnKeys = []
|
223 | for (key in options.template) {
|
224 | (typeof options.template[key] === 'function' ? fnKeys : keys).push(key)
|
225 | }
|
226 | keys = keys.concat(fnKeys)
|
227 |
|
228 | |
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 | for (i = 0; i < keys.length; i++) {
|
241 | key = keys[i]
|
242 | parsedKey = key.replace(rkey, '$1')
|
243 | options.context.path.push(parsedKey)
|
244 | result[parsedKey] = Handle.gen(options.template[key], key, {
|
245 | currentContext: result,
|
246 | templateCurrentContext: options.template,
|
247 | path: options.context.path
|
248 | })
|
249 | options.context.path.pop()
|
250 |
|
251 | inc = key.match(rkey)
|
252 | if (inc && inc[2] && Util.type(options.template[key]) === 'number') {
|
253 | options.template[key] += parseInt(inc[2], 10)
|
254 | }
|
255 | }
|
256 | }
|
257 | return result
|
258 | },
|
259 | number: function(options) {
|
260 | var result, parts, i;
|
261 | if (options.rule.point) {
|
262 | options.template += ''
|
263 | parts = options.template.split('.')
|
264 |
|
265 |
|
266 |
|
267 |
|
268 | parts[0] = options.rule.range ? options.rule.count : parts[0]
|
269 | parts[1] = (parts[1] || '').slice(0, options.rule.dcount)
|
270 | for (i = 0; parts[1].length < options.rule.dcount; i++) {
|
271 | parts[1] += Random.character('number')
|
272 | }
|
273 | result = parseFloat(parts.join('.'), 10)
|
274 | } else {
|
275 |
|
276 | result = options.rule.range && !options.rule.parameters[2] ? options.rule.count : options.template
|
277 | }
|
278 | return result
|
279 | },
|
280 | boolean: function(options) {
|
281 | var result;
|
282 |
|
283 |
|
284 | result = options.rule.parameters ? Random.bool(options.rule.min, options.rule.max, options.template) : options.template
|
285 | return result
|
286 | },
|
287 | string: function(options) {
|
288 | var result = '',
|
289 | i, placeholders, ph, phed;
|
290 | if (options.template.length) {
|
291 |
|
292 | for (i = 0; i < options.rule.count; i++) {
|
293 | result += options.template
|
294 | }
|
295 |
|
296 | placeholders = result.match(rplaceholder) || []
|
297 | for (i = 0; i < placeholders.length; i++) {
|
298 | ph = placeholders[i]
|
299 |
|
300 | if (/^\\/.test(ph)) {
|
301 | placeholders.splice(i--, 1)
|
302 | continue
|
303 | }
|
304 | phed = Handle.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext)
|
305 |
|
306 | if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) {
|
307 | result = phed
|
308 | break
|
309 |
|
310 | if (Util.isNumeric(phed)) {
|
311 | result = parseFloat(phed, 10)
|
312 | break
|
313 | }
|
314 | if (/^(true|false)$/.test(phed)) {
|
315 | result = phed === 'true' ? true :
|
316 | phed === 'false' ? false :
|
317 | phed
|
318 | break
|
319 | }
|
320 | }
|
321 | result = result.replace(ph, phed)
|
322 | }
|
323 | } else {
|
324 |
|
325 |
|
326 | result = options.rule.range ? Random.string(options.rule.count) : options.template
|
327 | }
|
328 | return result
|
329 | },
|
330 | 'function': function(options) {
|
331 | return options.template.call(options.context.currentContext)
|
332 | }
|
333 | })
|
334 |
|
335 | Handle.extend({
|
336 | _all: function() {
|
337 | var re = {};
|
338 | for (var key in Random) re[key.toLowerCase()] = key
|
339 | return re
|
340 | },
|
341 | placeholder: function(placeholder, obj, templateContext) {
|
342 |
|
343 | rplaceholder.exec('')
|
344 | var parts = rplaceholder.exec(placeholder),
|
345 | key = parts && parts[1],
|
346 | lkey = key && key.toLowerCase(),
|
347 | okey = this._all()[lkey],
|
348 | params = parts && parts[2] || ''
|
349 |
|
350 |
|
351 | try {
|
352 |
|
353 | |
354 |
|
355 |
|
356 |
|
357 |
|
358 |
|
359 | params = eval('(function(){ return [].splice.call(arguments, 0 ) })(' + params + ')')
|
360 | } catch (error) {
|
361 |
|
362 |
|
363 |
|
364 |
|
365 | params = parts[2].split(/,\s*/)
|
366 | }
|
367 |
|
368 |
|
369 | if (obj && (key in obj)) return obj[key]
|
370 |
|
371 | if (templateContext &&
|
372 | (typeof templateContext === 'object') &&
|
373 | (key in templateContext) &&
|
374 | (placeholder !== templateContext[key])
|
375 | ) {
|
376 | templateContext[key] = Handle.gen(templateContext[key], key, {
|
377 | currentContext: obj,
|
378 | templateCurrentContext: templateContext
|
379 | })
|
380 | return templateContext[key]
|
381 | }
|
382 |
|
383 | if (!(key in Random) && !(lkey in Random) && !(okey in Random)) return placeholder
|
384 |
|
385 | for (var i = 0; i < params.length; i++) {
|
386 | rplaceholder.exec('')
|
387 | if (rplaceholder.test(params[i])) {
|
388 | params[i] = Handle.placeholder(params[i], obj)
|
389 | }
|
390 | }
|
391 |
|
392 | var handle = Random[key] || Random[lkey] || Random[okey]
|
393 | switch (Util.type(handle)) {
|
394 | case 'array':
|
395 | return Random.pick(handle)
|
396 | case 'function':
|
397 | var re = handle.apply(Random, params)
|
398 | if (re === undefined) re = ''
|
399 | return re
|
400 | }
|
401 | }
|
402 | })
|
403 |
|
\ | No newline at end of file |