1 | 'use strict';
|
2 |
|
3 | var test = require('tap').test
|
4 | , cls = require('../context.js')
|
5 | , domain = require('domain')
|
6 | ;
|
7 |
|
8 | test("continuation-local storage glue with a throw in the continuation chain",
|
9 | function (t) {
|
10 | var namespace = cls.createNamespace('test');
|
11 | namespace.run(function () {
|
12 | var d = domain.create();
|
13 | namespace.set('outer', true);
|
14 |
|
15 | d.on('error', function (blerg) {
|
16 | t.equal(blerg.message, "explicitly nonlocal exit", "got the expected exception");
|
17 | t.ok(namespace.get('outer'), "outer context is still active");
|
18 | t.notOk(namespace.get('inner'), "inner context should have been exited by throw");
|
19 | t.equal(namespace._set.length, 1, "should be back to outer state");
|
20 |
|
21 | cls.destroyNamespace('test');
|
22 | t.end();
|
23 | });
|
24 |
|
25 |
|
26 | process.nextTick(d.bind(function () {
|
27 | t.ok(namespace.get('outer'), "outer mutation worked");
|
28 | t.notOk(namespace.get('inner'), "inner mutation hasn't happened yet");
|
29 |
|
30 | namespace.run(function () {
|
31 | namespace.set('inner', true);
|
32 | throw new Error("explicitly nonlocal exit");
|
33 | });
|
34 | }));
|
35 | });
|
36 | });
|
37 |
|
38 | test("synchronous throw attaches the context", function (t) {
|
39 | t.plan(3);
|
40 |
|
41 | var namespace = cls.createNamespace('cls@synchronous');
|
42 | namespace.run(function () {
|
43 | namespace.set('value', 'transaction clear');
|
44 | try {
|
45 | namespace.run(function () {
|
46 | namespace.set('value', 'transaction set');
|
47 | throw new Error('cls@synchronous explosion');
|
48 | });
|
49 | }
|
50 | catch (e) {
|
51 | t.ok(namespace.fromException(e), "context was attached to error");
|
52 | t.equal(namespace.fromException(e)['value'], 'transaction set',
|
53 | "found the inner value");
|
54 | }
|
55 |
|
56 | t.equal(namespace.get('value'), 'transaction clear', "everything was reset");
|
57 | });
|
58 |
|
59 | cls.destroyNamespace('cls@synchronous');
|
60 | });
|
61 |
|
62 | test("throw in process.nextTick attaches the context", function (t) {
|
63 | t.plan(3);
|
64 |
|
65 | var namespace = cls.createNamespace('cls@nexttick');
|
66 |
|
67 | var d = domain.create();
|
68 | d.on('error', function (e) {
|
69 | t.ok(namespace.fromException(e), "context was attached to error");
|
70 | t.equal(namespace.fromException(e)['value'], 'transaction set',
|
71 | "found the inner value");
|
72 |
|
73 | cls.destroyNamespace('cls@nexttick');
|
74 | });
|
75 |
|
76 | namespace.run(function () {
|
77 | namespace.set('value', 'transaction clear');
|
78 |
|
79 |
|
80 | process.nextTick(d.bind(function () {
|
81 | namespace.run(function () {
|
82 | namespace.set('value', 'transaction set');
|
83 | throw new Error("cls@nexttick explosion");
|
84 | });
|
85 | }));
|
86 |
|
87 | t.equal(namespace.get('value'), 'transaction clear', "everything was reset");
|
88 | });
|
89 | });
|
90 |
|
91 | test("throw in setTimeout attaches the context", function (t) {
|
92 | t.plan(3);
|
93 |
|
94 | var namespace = cls.createNamespace('cls@nexttick');
|
95 | var d = domain.create();
|
96 |
|
97 | d.on('error', function (e) {
|
98 | t.ok(namespace.fromException(e), "context was attached to error");
|
99 | t.equal(namespace.fromException(e)['value'], 'transaction set',
|
100 | "found the inner value");
|
101 |
|
102 | cls.destroyNamespace('cls@nexttick');
|
103 | });
|
104 |
|
105 | namespace.run(function () {
|
106 | namespace.set('value', 'transaction clear');
|
107 |
|
108 |
|
109 | setTimeout(d.bind(function () {
|
110 | namespace.run(function () {
|
111 | namespace.set('value', 'transaction set');
|
112 | throw new Error("cls@nexttick explosion");
|
113 | });
|
114 | }));
|
115 |
|
116 | t.equal(namespace.get('value'), 'transaction clear', "everything was reset");
|
117 | });
|
118 | });
|