Skip to content

Commit 0319e51

Browse files
committed
Some specs for comment filter
1 parent 2469643 commit 0319e51

5 files changed

Lines changed: 245 additions & 26 deletions

File tree

dist/CommentCoreLibrary.js

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,26 +1133,32 @@ var CommentFilter = (function () {
11331133
return true;
11341134
}
11351135
switch (rule.op) {
1136+
case '<':
1137+
return extracted < rule.value;
1138+
case '>':
1139+
return extracted > rule.value;
11361140
case '~':
11371141
case 'regexp':
11381142
return (new RegExp(rule.value)).test(extracted.toString());
11391143
case '=':
11401144
case 'eq':
1141-
return rule.value === extracted.toString();
1145+
return rule.value ===
1146+
((typeof extracted === 'number') ?
1147+
extracted : extracted.toString());
11421148
case 'NOT':
1143-
return !_match(rule.value, cmtData);
1149+
return !_match(rule.value, extracted);
11441150
case 'AND':
11451151
if (Array.isArray(rule.value)) {
11461152
return rule.value.every(function (r) {
1147-
return _match(r, cmtData);
1153+
return _match(r, extracted);
11481154
});
11491155
} else {
11501156
return false;
11511157
}
11521158
case 'OR':
11531159
if (Array.isArray(rule.value)) {
11541160
return rule.value.some(function (r) {
1155-
return _match(r, cmtData);
1161+
return _match(r, extracted);
11561162
});
11571163
} else {
11581164
return false;
@@ -1179,24 +1185,28 @@ var CommentFilter = (function () {
11791185
}
11801186

11811187
CommentFilter.prototype.doModify = function (cmt) {
1182-
for (var k=0; k < this.modifiers.length; k++) {
1183-
cmt = this.modifiers[k](cmt);
1184-
}
1185-
return cmt;
1188+
return this.modifiers.reduce(function (c, f) {
1189+
return f(c);
1190+
}, cmt);
11861191
};
11871192

11881193
CommentFilter.prototype.beforeSend = function (cmt) {
11891194
return cmt;
1190-
}
1195+
};
11911196

11921197
CommentFilter.prototype.doValidate = function (cmtData) {
1193-
if (cmtData.mode.toString() in this.allowTypes &&
1198+
if ((!this.allowUnknownTypes ||
1199+
cmtData.mode.toString() in this.allowTypes) &&
11941200
!this.allowTypes[cmtData.mode.toString()]) {
11951201
return false;
11961202
}
11971203
return this.rules.every(function (rule) {
11981204
// Decide if matched
1199-
var matched = _match(rule, cmtData);
1205+
try {
1206+
var matched = _match(rule, cmtData);
1207+
} catch (e) {
1208+
var matched = false;
1209+
}
12001210
return rule.mode === 'accept' ? matched : !matched;
12011211
});
12021212
};
@@ -1209,6 +1219,9 @@ var CommentFilter = (function () {
12091219
};
12101220

12111221
CommentFilter.prototype.addModifier = function (f) {
1222+
if (typeof f !== 'function') {
1223+
throw new Error('Modifiers need to be functions.');
1224+
}
12121225
this.modifiers.push(f);
12131226
};
12141227

dist/CommentCoreLibrary.min.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
'use strict'
2+
describe 'CommentFilter', ->
3+
filter = null
4+
comment =
5+
'mode': 1
6+
'stime': 0
7+
'text': 'Foo Bar Baz'
8+
'date': 1000
9+
'size': 25
10+
'color': 0xffffff
11+
commentAlt =
12+
'mode': 1
13+
'stime': 0
14+
'text': 'Foo Bar Baz Foz'
15+
'date': 2000
16+
'size': 50
17+
'color': 0xff0000
18+
19+
ruleAccept =
20+
'mode': 'accept'
21+
'subject': 'size'
22+
'op': '<'
23+
'value': 50
24+
ruleReject =
25+
'mode': 'reject'
26+
'subject': 'color'
27+
'op': '='
28+
'value': 0xffffff
29+
ruleNot =
30+
'mode': 'accept'
31+
'subject': ''
32+
'op': 'NOT'
33+
'value':
34+
'subject': 'text.length'
35+
'op': '<'
36+
'value': 15
37+
ruleOr =
38+
'mode': 'accept'
39+
'subject': ''
40+
'op': 'OR'
41+
'value': [
42+
{
43+
'subject': 'date'
44+
'op': '<'
45+
'value': 2000
46+
}
47+
{
48+
'subject': 'text'
49+
'op': '~'
50+
'value': '.oz'
51+
}
52+
]
53+
54+
describe 'instance API', ->
55+
beforeEach ->
56+
filter = new CommentFilter()
57+
58+
'doModify beforeSend doValidate addRule
59+
addModifier'.split(/\s/).forEach (method)->
60+
61+
it "has method: '#{method}'", ->
62+
expect(typeof filter[method]).toBe 'function'
63+
64+
describe 'defaults', ->
65+
it 'does not have any modifiers', ->
66+
expect(filter.modifiers.length).toBe 0
67+
68+
it 'does not have any rules', ->
69+
expect(filter.rules.length).toBe 0
70+
71+
describe '.doModify', ->
72+
beforeEach ->
73+
filter = new CommentFilter()
74+
75+
it 'does nothing if no modifier', ->
76+
expect(filter.doModify comment).toBe comment
77+
78+
it 'executes modifier', ->
79+
spy = sinon.stub().returns('Foo')
80+
filter.addModifier spy
81+
expect(filter.doModify comment).toBe 'Foo'
82+
expect(spy).toHaveBeenCalledWith(comment)
83+
84+
describe '.beforeSend', ->
85+
it 'does nothing', ->
86+
expect(filter.beforeSend comment).toBe comment
87+
88+
describe '.doValidate', ->
89+
alienModeComment =
90+
'mode': 1000
91+
'stime': 10
92+
'text': 'BAZ'
93+
'size': 10
94+
95+
beforeEach ->
96+
filter = new CommentFilter()
97+
98+
it 'passes valiadation valid mode', ->
99+
expect(filter.doValidate comment).toBe true
100+
101+
it 'fails validation invalid mode', ->
102+
filter.allowTypes['1'] = false
103+
expect(filter.doValidate comment).toBe false
104+
105+
it 'passes validation unknown mode', ->
106+
expect(filter.doValidate alienModeComment).toBe true
107+
108+
it 'fails validation if allowUnknownTypes false', ->
109+
filter.allowUnknownTypes = false
110+
expect(filter.doValidate alienModeComment).toBe false
111+
112+
it 'executes accept rules', ->
113+
filter.addRule ruleAccept
114+
expect(filter.doValidate comment).toBe true
115+
expect(filter.doValidate commentAlt).toBe false
116+
117+
it 'executes reject rules', ->
118+
filter.addRule ruleReject
119+
expect(filter.rules.length).toBe 1
120+
expect(filter.doValidate comment).toBe false
121+
expect(filter.doValidate commentAlt).toBe true
122+
123+
it 'implicitly ANDs rules', ->
124+
filter.addRule ruleAccept
125+
filter.addRule ruleReject
126+
expect(filter.doValidate comment).toBe false
127+
expect(filter.doValidate commentAlt).toBe false
128+
129+
it 'matches OR rules', ->
130+
filter.addRule ruleOr
131+
expect(filter.doValidate comment).toBe true
132+
expect(filter.doValidate commentAlt).toBe true
133+
134+
it 'matches NOT rules', ->
135+
filter.addRule ruleNot
136+
expect(filter.doValidate comment).toBe false
137+
expect(filter.doValidate commentAlt).toBe true
138+
139+
describe '.addRule', ->
140+
rule =
141+
'mode': 'reject',
142+
'subject': 'text',
143+
'op': '=',
144+
'value': 'Foo'
145+
146+
it 'adds a valid rule', ->
147+
filter.addRule rule
148+
expect(filter.rules.length).toBe 1
149+
expect(filter.rules[0]).toBe rule
150+
151+
it 'rejects adding invalid rule', ->
152+
expect( =>
153+
filter.addRule
154+
'mode': '???').toThrow()
155+
156+
describe '.addModifier', ->
157+
modifier = (cmt) ->
158+
cmt.color = 0xffffff
159+
cmt
160+
161+
it 'adds a valid modifier', ->
162+
filter.addModifier modifier
163+
expect(filter.modifiers.length).toBe 1
164+
expect(filter.modifiers[0]).toBe modifier
165+
166+
it 'rejects invalid modifier', ->
167+
expect( => filter.addModifier 'Boo').toThrow()
168+

spec/filter/SimpleFilter_spec.coffee

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/filter/CommentFilter.js

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
*/
66
var CommentFilter = (function () {
77

8+
/**
9+
* Matches a rule against an input that could be the full or a subset of
10+
* the comment data.
11+
*
12+
* @param rule - rule object to match
13+
* @param cmtData - full or portion of comment data
14+
* @return boolean indicator of match
15+
*/
816
function _match (rule, cmtData) {
917
var path = rule.subject.split('.');
1018
var extracted = cmtData;
@@ -26,26 +34,32 @@ var CommentFilter = (function () {
2634
return true;
2735
}
2836
switch (rule.op) {
37+
case '<':
38+
return extracted < rule.value;
39+
case '>':
40+
return extracted > rule.value;
2941
case '~':
3042
case 'regexp':
3143
return (new RegExp(rule.value)).test(extracted.toString());
3244
case '=':
3345
case 'eq':
34-
return rule.value === extracted.toString();
46+
return rule.value ===
47+
((typeof extracted === 'number') ?
48+
extracted : extracted.toString());
3549
case 'NOT':
36-
return !_match(rule.value, cmtData);
50+
return !_match(rule.value, extracted);
3751
case 'AND':
3852
if (Array.isArray(rule.value)) {
3953
return rule.value.every(function (r) {
40-
return _match(r, cmtData);
54+
return _match(r, extracted);
4155
});
4256
} else {
4357
return false;
4458
}
4559
case 'OR':
4660
if (Array.isArray(rule.value)) {
4761
return rule.value.some(function (r) {
48-
return _match(r, cmtData);
62+
return _match(r, extracted);
4963
});
5064
} else {
5165
return false;
@@ -71,25 +85,48 @@ var CommentFilter = (function () {
7185
};
7286
}
7387

88+
/**
89+
* Runs all modifiers against current comment
90+
*
91+
* @param cmt - comment to run modifiers on
92+
* @return modified comment
93+
*/
7494
CommentFilter.prototype.doModify = function (cmt) {
75-
for (var k=0; k < this.modifiers.length; k++) {
76-
cmt = this.modifiers[k](cmt);
77-
}
78-
return cmt;
95+
return this.modifiers.reduce(function (c, f) {
96+
return f(c);
97+
}, cmt);
7998
};
8099

100+
/**
101+
* Executes a method defined to be executed right before the comment object
102+
* (built from commentData) is placed onto the runline.
103+
*
104+
* @deprecated
105+
* @param cmt - comment data
106+
* @return cmt
107+
*/
81108
CommentFilter.prototype.beforeSend = function (cmt) {
82109
return cmt;
83-
}
110+
};
84111

112+
/**
113+
* Performs validation of the comment data before it is allowed to get sent
114+
*
115+
* @param cmtData - comment data
116+
*/
85117
CommentFilter.prototype.doValidate = function (cmtData) {
86-
if (cmtData.mode.toString() in this.allowTypes &&
118+
if ((!this.allowUnknownTypes ||
119+
cmtData.mode.toString() in this.allowTypes) &&
87120
!this.allowTypes[cmtData.mode.toString()]) {
88121
return false;
89122
}
90123
return this.rules.every(function (rule) {
91124
// Decide if matched
92-
var matched = _match(rule, cmtData);
125+
try {
126+
var matched = _match(rule, cmtData);
127+
} catch (e) {
128+
var matched = false;
129+
}
93130
return rule.mode === 'accept' ? matched : !matched;
94131
});
95132
};
@@ -102,6 +139,9 @@ var CommentFilter = (function () {
102139
};
103140

104141
CommentFilter.prototype.addModifier = function (f) {
142+
if (typeof f !== 'function') {
143+
throw new Error('Modifiers need to be functions.');
144+
}
105145
this.modifiers.push(f);
106146
};
107147

0 commit comments

Comments
 (0)