UNPKG

7.12 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3var path = require('path')
4 , advisable = require(path.resolve(__dirname, '..', 'lib', 'advisable'))
5 , target;
6
7function Target(val) {
8 this.val = val;
9}
10
11Target.prototype.syncFunc = function (a, b) {
12 console.log(
13 'Target.prototype.syncFunc, a = %d, b = %d, this.val = %d'
14 , a
15 , b
16 , this.val
17 );
18
19 return a + b + this.val;
20};
21
22Target.prototype.asyncFunc = function (a, b, callback) {
23 console.log(
24 'Target.prototype.asyncFunc, a = %d, b = %d, this.val = %d'
25 , a
26 , b
27 , this.val
28 );
29
30 process.nextTick(function () {
31 callback(null, a + b + this.val);
32 }.bind(this));
33};
34
35// Mixin sync advice
36advisable.sync.call(Target.prototype);
37
38// Mixin async advice
39advisable.async.call(Target.prototype);
40
41// All examples create a new Target instance and invoke advice methods on the
42// instance so that examples don't interfere with each other. Often, real
43// world usage will involve advising the prototype, not an individual instance,
44// so that all instances receive advice. That being said, advice can be mixed
45// into to _any_ JS object and applied to any function on the given object.
46
47// -----------------------------------------------------------------------------
48//
49// Synchronous Advice Examples
50//
51// -----------------------------------------------------------------------------
52
53// No advice
54target = new Target(1);
55
56// 10 + 100 + 1 => 111
57console.log('syncFunc, no advice: %d', target.syncFunc(10, 100));
58
59// -----------------------------------------------------------------------------
60
61// Before advice that increments target.val
62target = new Target(1);
63target.beforeSync('syncFunc', function (a, b) {
64 this.val++;
65});
66
67// 10 + 100 + 2 => 112
68console.log('syncFunc, increment before: %d', target.syncFunc(10, 100));
69
70// -----------------------------------------------------------------------------
71
72// Before advice that modifies arguments
73target = new Target(1);
74target.beforeSync('syncFunc', function (a, b) {
75 return [ a/10, b/10 ];
76}, { mutate: true });
77
78// 10/10 + 100/10 + 1 => 12
79console.log('syncFunc, divide args before: %d', target.syncFunc(10, 100));
80
81// -----------------------------------------------------------------------------
82
83// After advice that decrements target.val
84target = new Target(1);
85target.afterSync('syncFunc', function (a, b) {
86 this.val--;
87});
88
89// 10 + 100 + 1 => 111 (original return value)
90console.log('syncFunc, decrement after: %d', target.syncFunc(10, 100));
91
92// this.val is now 0
93console.log('syncFunc, decremented: %d', target.val);
94
95// -----------------------------------------------------------------------------
96
97// After advice that modifies the return value
98target = new Target(1);
99target.afterSync('syncFunc', function (v) {
100 return v * 2;
101}, { mutate: true });
102
103// (10/10 + 100/10 + 1) * 2 => 222
104console.log('syncFunc, double after: %d', target.syncFunc(10, 100));
105
106// -----------------------------------------------------------------------------
107
108// Around advice that simply observes
109target = new Target(1);
110target.aroundSync(
111 'syncFunc'
112, function (a, b) {
113 console.log('around:before called with args: %d, %d', a, b);
114 }
115, function (a, b) {
116 console.log('around:after called with args: %d, %d', a, b);
117 }
118);
119
120// 10 + 100 + 1 => 111
121console.log('syncFunc, around advice: %d', target.syncFunc(10, 100));
122
123// -----------------------------------------------------------------------------
124
125// Mutated around advice
126target = new Target(1);
127target.aroundSync(
128 'syncFunc'
129, function (a, b) {
130 console.log('around:before called with args: %d, %d', a, b);
131 return [ a * 3, b * 3 ];
132 }
133, function (v) {
134 console.log('around:after called with arg: %d', v);
135 return v + 123;
136 }
137, { mutate: true }
138);
139
140// ((10*3) + (100*3) + 1) + 123 => 454
141console.log('syncFunc, mutated around advice: %d', target.syncFunc(10, 100));
142
143// -----------------------------------------------------------------------------
144//
145// Asynchronous Advice Examples
146//
147// -----------------------------------------------------------------------------
148
149// No advice
150target = new Target(1);
151
152// 10 + 100 + 1 => 111
153target.asyncFunc(10, 100, function (err, result) {
154 console.log('asyncFunc, no advice: %d', result);
155});
156
157// -----------------------------------------------------------------------------
158
159// Before advice that increments target.val
160target = new Target(1);
161target.before('asyncFunc', function (a, b, callback) {
162 this.val++;
163 // Non-mutated async advice must call back, but the error (first) argument
164 // is the only argument considered.
165 callback();
166});
167
168// 10 + 100 + 2 => 112
169target.asyncFunc(10, 100, function (err, result) {
170 console.log('asyncFunc, increment before: %d', result);
171});
172
173// -----------------------------------------------------------------------------
174
175// Before advice that modifies arguments
176target = new Target(1);
177target.before('asyncFunc', function (a, b, callback) {
178 callback(null, a/10, b/10);
179}, { mutate: true });
180
181// 10/10 + 100/10 + 1 => 12
182target.asyncFunc(10, 100, function (err, result) {
183 console.log('asyncFunc, divide args before: %d', result);
184});
185
186// -----------------------------------------------------------------------------
187
188// After advice that decrements target.val
189target = new Target(1);
190target.after('asyncFunc', function (a, b, callback) {
191 this.val--;
192 callback();
193});
194
195// 10 + 100 + 1 => 111 (original return value)
196target.asyncFunc(10, 100, function (err, result) {
197 console.log('asyncFunc, decrement after: %d', result);
198 // target.val is now 0
199 console.log('asyncFunc, decremented: %d', this.val);
200}.bind(target));
201
202// -----------------------------------------------------------------------------
203
204// After advice that modifies the return value
205target = new Target(1);
206target.after('asyncFunc', function (v, callback) {
207 callback(null, v * 2);
208}, { mutate: true });
209
210// (10/10 + 100/10 + 1) * 2 => 222
211target.asyncFunc(10, 100, function (err, result) {
212 console.log('asyncFunc, double after: %d', result);
213});
214
215// -----------------------------------------------------------------------------
216
217// Around advice that simply observes
218target = new Target(1);
219target.around(
220 'asyncFunc'
221, function (a, b, callback) {
222 console.log('around:before called with args: %d, %d', a, b);
223 callback();
224 }
225, function (a, b, callback) {
226 console.log('around:after called with args: %d, %d', a, b);
227 callback();
228 }
229);
230
231// 10 + 100 + 1 => 111
232target.asyncFunc(10, 100, function (err, result) {
233 console.log('asyncFunc, around advice: %d', result);
234});
235
236// -----------------------------------------------------------------------------
237
238// Mutated around advice
239target = new Target(1);
240target.around(
241 'asyncFunc'
242, function (a, b, callback) {
243 console.log('around:before called with args: %d, %d', a, b);
244 callback(null, a * 3, b * 3);
245 }
246, function (v, callback) {
247 console.log('around:after called with arg: %d', v);
248 callback(null, v + 123);
249 }
250, { mutate: true }
251);
252
253// ((10*3) + (100*3) + 1) + 123 => 454
254target.asyncFunc(10, 100, function (err, result) {
255 console.log('syncFunc, mutated around advice: %d', result);
256});