Completed
Push — master ( 54b84a...25fb7a )
by Esaú
02:10
created

spec/ClassCastException.spec.js   C

Complexity

Total Complexity 54
Complexity/F 1.93

Size

Lines of Code 212
Function Count 28

Duplication

Duplicated Lines 212
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
wmc 54
c 1
b 0
f 0
nc 512
mnd 3
bc 39
fnc 28
dl 212
loc 212
rs 6.8539
bpm 1.3928
cpm 1.9285
noi 1

1 Function

Rating   Name   Duplication   Size   Complexity  
B ClassCastException.spec.js ➔ ??? 195 195 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like spec/ClassCastException.spec.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
// spec/ClassCastException.spec.js
2 View Code Duplication
"use strict";
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3
4
// :: DEPENDENCIES
5
6
// load native dependencies
7
const path = require("path");
8
9
// load local dependencies
10
const root               = path.dirname(__dirname);
11
const Throwable          = require(path.join(root, "Throwable.js"));
12
const Exception          = require(path.join(root, "Exception.js"));
13
const RuntimeException   = require(path.join(root, "RuntimeException.js"));
14
const ClassCastException = require(path.join(root, "ClassCastException.js"));
15
16
// :: TESTING
17
18
// test the ClassCastException 'class'
19
describe("ClassCastException", () => {
20
21
    // :: INHERITED PROTOTYPE
22
23
    it("should inherit from 'Object'", () => {
24
        expect(new ClassCastException()).toEqual(jasmine.any(Object));
25
    });
26
27
	it("should inherit from 'Throwable'", () => {
28
		expect(new ClassCastException()).toEqual(jasmine.any(Throwable));
29
	});
30
31
	it("should inherit from 'Exception'", () => {
32
		expect(new ClassCastException()).toEqual(jasmine.any(Exception));
33
	});
34
35
    it("should inherit from 'RuntimeException'", () => {
36
        expect(new ClassCastException()).toEqual(jasmine.any(RuntimeException));
37
    });
38
39
	it("should have a prototype method named 'toString()'", () => {
40
		expect(ClassCastException.prototype).toHaveMethod("toString");
41
	});
42
43
	it("should have a prototype method named 'native()'", () => {
44
		expect(ClassCastException.prototype).toHaveMethod("native");
45
	});
46
47
	it("should have a prototype property string named 'name'", () => {
48
		expect(ClassCastException.prototype).toHaveString("name");
49
	});
50
51
	it("should have a prototype property string named 'message'", () => {
52
		expect(ClassCastException.prototype).toHaveString("message");
53
	});
54
55
	it("should have a prototype property string named 'code'", () => {
56
		expect(ClassCastException.prototype).toHaveMember("code");
57
	});
58
59
    // :: EXTENDED PROTOTYPE
60
61
    // :: PROTOTYPE VALUES
62
63
    it("should have the 'class' name in the prototype property named 'name'", () => {
64
        expect(ClassCastException.prototype.name).toEqual("ClassCastException");
65
    });
66
67
    it("should have a dummy default value as message", () => {
68
        expect(ClassCastException.prototype.message).toEqual("thrown");
69
    });
70
71
    it("should have a null default value as code", () => {
72
        expect(ClassCastException.prototype.code).toBeNull();
73
    });
74
75
    // :: CONSTRUCTOR
76
77
    it("should instantiate without parameters", () => {
78
        let arg1, arg2, test;
79
        test = (() => new ClassCastException(arg1, arg2));
80
        for (let i = 0; i < 2; i += 1) {
81
            for (let j = 0; j < 2; j += 1) {
82
                arg1 = (i % 2 === 0 ? undefined : null);
83
                arg2 = (j % 2 === 0 ? undefined : null);
84
                expect(test).not.toThrowError("parameter 'name' must be a 'string'");
85
                expect(test).not.toThrowError("parameter 'message' must be a 'string'");
86
                expect(test).not.toThrowError("parameter 'code' must be a 'number'");
87
            }
88
        }
89
        test = (() => new ClassCastException());
90
        expect(test).not.toThrowError("parameter 'name' must be a 'string'");
91
        expect(test).not.toThrowError("parameter 'message' must be a 'string'");
92
        expect(test).not.toThrowError("parameter 'code' must be a 'number'");
93
    });
94
95
    it("should instantiate with parameters", () => {
96
        let arg1, arg2, test1, test2;
97
        const args1 = [undefined, null, ClassCastException.prototype.message];
98
        const args2 = [undefined, null, Math.round(Math.random() * 0xFFFFFFFF)];
99
        test1       = (() => new ClassCastException(arg1));
100
        test2       = (() => new ClassCastException(arg1, arg2));
101
        for (let i = 0; i < args1.length; i += 1) {
102
            arg1 = args1[i];
103
            for (let j = 0; j < args2.length; j += 1) {
104
                arg2 = args2[j];
105
                expect(test2).not.toThrowError("parameter 'message' must be a 'string'");
106
                expect(test2).not.toThrowError("parameter 'code' must be a 'number'");
107
            }
108
            expect(test1).not.toThrowError("parameter 'message' must be a 'string'");
109
            expect(test1).not.toThrowError("parameter 'code' must be a 'number'");
110
        }
111
    });
112
113
    it("should throw an Error if 'message' or 'code' are invalid parameters", () => {
114
        let arg1, arg2, test21, test22, test11;
115
        const noStr = [{}, true, false, 42, 3.1416, -42, -3.1416, () => null];
116
        const noNmb = [{}, true, false, '', "qwerty", () => null];
117
        test22      = (() => new ClassCastException(arg1, arg2));
118
        test21      = (() => new ClassCastException(null, arg2));
119
        test11      = (() => new ClassCastException(arg1));
120
        if (typeof Symbol === "function") {
121
            noStr.push(Symbol("symbol"));
122
            noNmb.push(Symbol("symbol"));
123
        }
124
        for (let i = 0; i < noStr.length; i += 1) {
125
            arg1 = noStr[i];
126
            for (let j = 0; j < noNmb.length; j += 1) {
127
                arg2 = noNmb[j];
128
                expect(test22).toThrowError("parameter 'message' must be a 'string'");
129
                expect(test21).toThrowError("parameter 'code' must be a 'number'");
130
            }
131
            expect(test11).toThrowError("parameter 'message' must be a 'string'");
132
        }
133
    });
134
135
    // :: MEMBER PROPERTIES
136
137
    it("should have all correct properties once instantiated", () => {
138
        const message = "asdf";
139
        const code    = Math.round(Math.random() * 0xFFFFFFFF);
140
        for (let i = 0; i < 2; i += 1) {
141
            const arg1    = (i % 2 === 0 ? message : null);
142
            const source1 = new ClassCastException(arg1);
143
            for (let j = 0; j < 2; j += 1) {
144
                const arg2    = (j % 2 === 0 ? code : null);
145
                const source2 = new ClassCastException(arg1, arg2);
146
                if (i % 2 === 0) {
147
                    expect(source1.message).toEqual(message);
148
                    expect(source2.message).toEqual(message);
149
                } else {
150
                    expect(source1.message).toEqual(ClassCastException.prototype.message);
151
                    expect(source2.message).toEqual(ClassCastException.prototype.message);
152
                }
153
                if (j % 2 === 0) {
154
                    expect(source2.code).toEqual(code);
155
                } else {
156
                    expect(source2.code).toBeNull();
157
                }
158
                expect(source1.code).toBeNull();
159
            }
160
        }
161
    });
162
163
    // :: MEMBER METHODS
164
165
    const name    = "ClassCastException";
0 ignored issues
show
Unused Code introduced by
The constant name seems to be never used. Consider removing it.
Loading history...
166
    const message = "asdf";
167
    const code    = Math.round(Math.random() * 0xFFFFFFFF);
168
169
    it("#toString()", () => {
170
        for (let i = 0; i < 2; i += 1) {
171
            const arg1    = (i % 2 === 0 ? message : null);
172
            const source1 = new ClassCastException(arg1);
173
            for (let j = 0; j < 2; j += 1) {
174
                const arg2    = (j % 2 === 0 ? code : null);
175
                const source2 = new ClassCastException(arg1, arg2);
176
                const str1    = source1.toString();
177
                const str2    = source2.toString();
178
                let exp1, exp2;
179
                exp1 = exp2 = "ClassCastException";
180
                if (j % 2 === 0) {
181
                    exp2 += " (0x" + code.toString(16) + ')';
182
                }
183
                if (i % 2 === 0) {
184
                    exp1 += ": " + message + '.';
185
                    exp2 += ": " + message + '.';
186
                } else {
187
                    exp1 += ": " + ClassCastException.prototype.message + '.';
188
                    exp2 += ": " + ClassCastException.prototype.message + '.';
189
                }
190
                expect(str1).toEqual(exp1);
191
                expect(str2).toEqual(exp2);
192
            }
193
        }
194
    });
195
196
    it("#native()", () => {
197
        for (let i = 0; i < 2; i += 1) {
198
            const arg1    = (i % 2 === 0 ? message : null);
199
            const source1 = new ClassCastException(arg1);
200
            for (let j = 0; j < 2; j += 1) {
201
                const arg2    = (j % 2 === 0 ? code : null);
202
                const source2 = new ClassCastException(arg1, arg2);
203
                const err1    = source1.native();
204
                const err2    = source2.native();
205
                const exp1    = (i % 2 === 0 ? message : ClassCastException.prototype.message);
206
                const exp2    = exp1;
207
                expect(err1).toEqual(new Error(exp1));
208
                expect(err2).toEqual(new Error(exp2));
209
            }
210
        }
211
    });
212
213
});