Skip to content

Commit bdc3551

Browse files
committed
add unit tests for doesMQMatch()
1 parent e3a25b4 commit bdc3551

File tree

3 files changed

+394
-5
lines changed

3 files changed

+394
-5
lines changed

index.js

Lines changed: 159 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ See the accompanying LICENSE file for terms.
66

77
'use strict';
88

9-
module.exports = match;
9+
module.exports = matchMQ;
1010

1111
// -----------------------------------------------------------------------------
1212

13-
function match(mediaQuery, values) {
14-
return parseQuery(mediaQuery);
13+
function matchMQ(mediaQuery, values) {
14+
//return parseQuery(mediaQuery);
15+
return doesMQMatch(mediaQuery, values);
1516
}
1617

1718
// -- Utilities ----------------------------------------------------------------
@@ -91,3 +92,158 @@ function toPx(length) {
9192
default : return value;
9293
}
9394
}
95+
96+
function toDecimal(ratio) {
97+
var numbers = ratio.match(/^(\d+)\s*\/\s*(\d+)$/);
98+
return numbers[1] / numbers[2];
99+
}
100+
101+
function doesMQMatch(mq, query) {
102+
103+
//get the AST
104+
var parsed = parseQuery(mq),
105+
didMQMatch = true;
106+
107+
parsed.forEach(function (p) {
108+
p.expressions.forEach(function (e) {
109+
//if the query contains this property, then we need to do a check to see if it passes the threshold. If any of the matches are false, then the media query does not pass.
110+
var match = checkForMatch(e, query);
111+
if (!match) {
112+
didMQMatch = false;
113+
}
114+
});
115+
});
116+
117+
return didMQMatch;
118+
}
119+
120+
function checkForMatch (exp, query) {
121+
var val = query[exp.property],
122+
isMatch = false;
123+
124+
//if there's a value for this property, then we need to see if it is within the threshold
125+
//doing an explicit undefined check here so that `0` goes through.
126+
if (val !== undefined) {
127+
switch (exp.property) {
128+
case 'device-width':
129+
case 'device-height':
130+
case 'width':
131+
case 'height':
132+
isMatch = doesLengthPass(exp, val);
133+
break;
134+
135+
case 'color':
136+
case 'color-index':
137+
case 'monochrome':
138+
isMatch = doesColorPass(exp, val);
139+
break;
140+
141+
case 'resolution':
142+
isMatch = doesResolutionPass(exp, val);
143+
break;
144+
145+
case 'aspect-ratio':
146+
isMatch = doesAspectRatioPass(exp, val);
147+
break;
148+
149+
case 'orientation':
150+
case 'scan':
151+
isMatch = doesScanPass(exp, val);
152+
break;
153+
154+
case 'grid':
155+
isMatch = doesGridPass(exp, val);
156+
break;
157+
158+
}
159+
160+
return isMatch;
161+
}
162+
163+
//if there is not a value for the property, then we can return true.
164+
else {
165+
return true;
166+
}
167+
}
168+
169+
function checkMinMax (expVal, queryVal, modifier) {
170+
switch (modifier) {
171+
case 'min':
172+
//if the value we want is greater than the minimum required, then it's true.
173+
if (expVal <= queryVal) {
174+
return true;
175+
}
176+
break;
177+
case 'max':
178+
//if the value we want is less than or equal to the maximum required, then it's true.
179+
if (expVal >= queryVal) {
180+
return true;
181+
}
182+
break;
183+
default:
184+
//sometimes we may not have a modifier. in this case, the value has to be an exact match.
185+
if (expVal === queryVal) {
186+
return true;
187+
}
188+
break;
189+
}
190+
191+
return false;
192+
}
193+
194+
function doesTypePass (parsed, value) {
195+
var type = (value instanceof 'string') ? value : 'object'
196+
if (parsed === value) {
197+
return true;
198+
}
199+
else {
200+
return false;
201+
}
202+
}
203+
204+
function doesLengthPass (exp, val) {
205+
var expToPx = toPx(exp.value),
206+
valToPx = toPx(val);
207+
208+
return checkMinMax(expToPx, valToPx, exp.modifier);
209+
}
210+
211+
function doesColorPass (exp, val) {
212+
var expInt;
213+
214+
//this is the (min-width: foo) and (color) use case, which means "any colored device"
215+
if (!exp.value) {
216+
if (val === 0) return false;
217+
else return true;
218+
}
219+
220+
//assigning after exp.value `undefined` check.
221+
expInt = parseInt(exp.value);
222+
return checkMinMax(expInt, val, exp.modifier);
223+
224+
}
225+
226+
function doesResolutionPass (exp, val) {
227+
var expDpi = toDpi(exp.value),
228+
valDpi = (typeof val === 'string') ? toDpi(val) : val;
229+
230+
return checkMinMax(expDpi, valDpi, exp.modifier);
231+
}
232+
233+
function doesAspectRatioPass (exp, val) {
234+
var expDec = toDecimal(exp.value),
235+
valDec = (typeof val === 'string') ? toDecimal(val) : val;
236+
return checkMinMax(expDec, valDec, exp.modifier);
237+
}
238+
239+
function doesScanPass (exp, val) {
240+
if (exp.value === val) {
241+
return true;
242+
}
243+
return false;
244+
}
245+
246+
function doesGridPass (exp, val) {
247+
//the only way grid would return false is if we explicitly had {grid: <falsy val>} in our query object.
248+
return !!val;
249+
}

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Determines if a given CSS Media Query matches a set of values.",
55
"main": "index.js",
66
"scripts": {
7-
"test": "echo \"Error: no test specified\" && exit 1"
7+
"test": "node_modules/.bin/mocha"
88
},
99
"repository": {
1010
"type": "git",
@@ -22,5 +22,9 @@
2222
"bugs": {
2323
"url": "https://github.com/ericf/css-media-match/issues"
2424
},
25-
"homepage": "https://github.com/ericf/css-media-match"
25+
"homepage": "https://github.com/ericf/css-media-match",
26+
"devDependencies": {
27+
"mocha": "~1.16.2",
28+
"chai": "~1.8.1"
29+
}
2630
}

0 commit comments

Comments
 (0)