user-friendly.js revision 0dd7db90ddc84e1fe5b102a52f8966faa923c124
var ScalarComparator = {}, ScreenComparator = {}, MultiValueComparator = {}, UserAgentComparator = {}, GeolocationComparator = {}, DEBUG = logger;
var config = {
maxPenaltyPoints: 200,
attributes: {
screen: {
required: true,
args: {
penaltyPoints: 50
}
},
plugins: {
required: false,
args: {
maxDifferences: 5,
penaltyPoints: 100
}
}
},
fonts: {
required: false,
args: {
penaltyPoints: 100
}
}
},
timezone: {
timezone: {
required: false,
args: {
penaltyPoints: 100
}
}
},
userAgent: {
required: true,
args: {
ignoreVersion: true,
penaltyPoints: 100
}
},
geolocation: {
required: false,
args: {
penaltyPoints: 100
}
}
}
};
//---------------------------------------------------------------------------//
// Comparator functions //
//---------------------------------------------------------------------------//
/**
* Compares two simple objects (String|Number) and if they are equal then returns a ComparisonResult with zero
* penalty points assigned, otherwise returns a ComparisonResult with the given number of penalty points assigned.
*
* @param currentValue (String|Number) The current value.
* @param storedValue (String|Number) The stored value.
* @param config: {
* "penaltyPoints": (Number) The number of penalty points.
* }
* @return ComparisonResult.
*/
if (DEBUG.messageEnabled()) {
}
return ComparisonResult.ZERO_PENALTY_POINTS;
}
if (storedValue !== null) {
}
} else if (currentValue !== null) {
return new ComparisonResult(true);
}
return ComparisonResult.ZERO_PENALTY_POINTS;
};
/**
* Compares two screens and if they are equal then returns a ComparisonResult with zero penalty points assigned,
* otherwise returns a ComparisonResult with the given number of penalty points assigned.
*
* @param currentValue: {
* "screenWidth": (Number) The current client screen width.
* "screenHeight": (Number) The current client screen height.
* "screenColourDepth": (Number) The current client screen colour depth.
* }
* @param storedValue: {
* "screenWidth": (Number) The stored client screen width.
* "screenHeight": (Number) The stored client screen height.
* "screenColourDepth": (Number) The stored client screen colour depth.
* }
* @param config: {
* "penaltyPoints": (Number) The number of penalty points.
* }
* @return ComparisonResult
*/
if (DEBUG.messageEnabled()) {
}
// if comparing against old profile
if (storedValue === undefined) {
}
var comparisonResults = [
} else {
}
};
/**
* Splits both values using delimiter, trims every value and compares collections of values.
* Returns zero-result for same multi-value attributes.
*
* If collections are not same checks if number of differences is less or equal maxDifferences or
* percentage of difference is less or equal maxPercentageDifference.
*
* If yes then returns zero-result with additional info, else returns penaltyPoints-result.
*
* @param currentValue: (String) The current value.
* @param storedValue: (String) The stored value.
* @param config: {
* "maxPercentageDifference": (Number) The max difference percentage in the values,
* before the penalty is assigned.
* "maxDifferences": (Number) The max number of differences in the values,
* before the penalty points are assigned.
* "penaltyPoints": (Number) The number of penalty points.
* }
* @return ComparisonResult
*/
if (DEBUG.messageEnabled()) {
}
var delimiter = ";";
return new ComparisonResult(true);
}
if (DEBUG.messageEnabled()) {
}
if (maxNumberOfElements === 0) {
return ComparisonResult.ZERO_PENALTY_POINTS;
}
if (numberOfTheSameElements === maxNumberOfElements) {
return ComparisonResult.ZERO_PENALTY_POINTS;
}
if (DEBUG.messageEnabled()) {
}
}
if (DEBUG.messageEnabled()) {
}
}
if (DEBUG.messageEnabled()) {
+ config.maxDifferences);
}
return new ComparisonResult(true);
};
/**
* Compares two User Agent Strings and if they are equal then returns a ComparisonResult with zero penalty
* points assigned, otherwise returns a ComparisonResult with the given number of penalty points assigned.
*
* @param currentValue (String) The current value.
* @param storedValue (String) The stored value.
* @param config: {
* "ignoreVersion": (boolean) If the version numbers in the User Agent Strings should be ignore
* in the comparison.
* "penaltyPoints": (Number) The number of penalty points.
* }
* @return A ComparisonResult.
*/
if (DEBUG.messageEnabled()) {
}
if (config.ignoreVersion) {
// remove version number
}
};
/**
* Compares two locations, taking into account a degree of difference.
*
* @param currentValue: {
* "latitude": (Number) The current latitude.
* "longitude": (Number) The current longitude.
* }
* @param storedValue: {
* "latitude": (Number) The stored latitude.
* "longitude": (Number) The stored longitude.
* }
* @param config: {
* "allowedRange": (Number) The max difference allowed in the two locations, before the penalty is assigned.
* "penaltyPoints": (Number) The number of penalty points.
* }
* @return ComparisonResult
*/
if (DEBUG.messageEnabled()) {
}
// if comparing against old profile
if (storedValue === undefined) {
}
// both null
return ComparisonResult.ZERO_PENALTY_POINTS;
}
// current null, stored not null
}
// current not null, stored null
}
// both have values, therefore perform comparison
if (DEBUG.messageEnabled()) {
DEBUG.message("Distance between (" + currentValue.latitude + "," + currentValue.longitude + ") and (" +
}
return ComparisonResult.ZERO_PENALTY_POINTS;
}
if (DEBUG.messageEnabled()) {
}
return new ComparisonResult(true);
} else {
if (DEBUG.messageEnabled()) {
}
}
};
//---------------------------------------------------------------------------//
// Device Print Logic - DO NOT MODIFY //
//---------------------------------------------------------------------------//
// Utility functions
/**
* Returns true if evaluating function f on each element of the Array a returns true.
*
* @param a: (Array) The array of elements to evaluate
* @param f: (Function) A single argument function for mapping elements of the array to boolean.
* @return boolean.
*/
all = function(a, f) {
for (var i = 0; i < a.length; i++) {
if (f(a[i]) === false) {
return false;
}
}
return true;
}
/**
* Returns true if evaluating function f on any element of the Array a returns true.
*
* @param a: (Array) The array of elements to evaluate
* @param f: (Function) A single argument function for mapping elements of the array to boolean.
* @return boolean.
*/
any = function(a, f) {
for (var i = 0; i < a.length; i++) {
if (f(a[i]) === true) {
return true;
}
}
return false;
}
/**
* Calculates the distances between the two locations.
*
* @param first: {
* "latitude": (Number) The first latitude.
* "longitude": (Number) The first longitude.
* }
* @param second: {
* "latitude": (Number) The second latitude.
* "longitude": (Number) The second longitude.
* }
* @return Number The distance between the two locations.
*/
function degreesToRadians(degrees) {
}
function radiansToDegrees(radians) {
}
return dist;
};
/**
* Converts a String holding a delimited sequence of values into an array.
*
* @param text (String) The String representation of a delimited sequence of values.
* @param delimiter (String) The character delimiting values within the text String.
* @return (Array) The comma separated values.
*/
var results = [];
if (text === null) {
return results;
}
if (value !== "") {
}
}
return results;
};
/**
* Converts value to a percentage of range.
*
* @param value (Number) The actual number to be converted to a percentage.
* @param range (Number) The total number of values (i.e. represents 100%).
* @return (Number) The percentage.
*/
if (range === 0) {
return 0;
}
};
/**
* Creates a new array containing only those elements found in both arrays received as arguments.
*
* @param first (Array) The first array.
* @param second (Array) The second array.
* @return (Array) The elements that found in first and second.
*/
});
};
// ComparisonResult
/**
* Constructs an instance of a ComparisonResult with the given penalty points.
*
* @param penaltyPoints (Number) The penalty points for the comparison (defaults to 0).
* @param additionalInfoInCurrentValue (boolean) Whether the current value contains more information
* than the stored value (defaults to false).
*/
function ComparisonResult() {
var penaltyPoints = 0;
var additionalInfoInCurrentValue = false;
}
} else {
}
}
this.penaltyPoints = penaltyPoints;
}
/**
* Static method for functional programming.
*
* @return boolean true if comparisonResult.isSuccessful().
*/
return comparisonResult.isSuccessful();
};
/**
* Static method for functional programming.
*
* @return boolean true if comparisonResult.additionalInfoInCurrentValue.
*/
};
/**
* Comparison function that can be provided as an argument to array.sort
*/
return 0;
} else if (first === null) {
return -1;
} else if (second === null) {
return 1;
} else {
} else {
return (first.additionalInfoInCurrentValue ? 1 : 0) - (second.additionalInfoInCurrentValue ? 1 : 0);
}
}
};
/**
* Amalgamates the given ComparisonResult into this ComparisonResult.
*
* @param comparisonResult The ComparisonResult to include.
*/
}
};
/**
* Returns true if no penalty points have been assigned for the comparison.
*
* @return boolean true if the comparison was successful.
*/
};
function matchDevicePrint() {
if (!username) {
} else {
var getProfiles = function () {
function isExpiredProfile(devicePrintProfile) {
var expirationDate = new Date();
return lastSelectedDate < expirationDate;
}
function getNotExpiredProfiles() {
var results = [];
if (!isExpiredProfile(profile)) {
}
}
if (DEBUG.messageEnabled()) {
}
return results;
}
return getNotExpiredProfiles();
};
if (DEBUG.messageEnabled()) {
}
var devicePrintProfiles = getProfiles();
return null;
}
}
return value;
}
var attributePaths = [];
for (var attributeName in attributeConfig) {
var tmp = a(devicePrint, devicePrintProfiles, attributeConfig[attributeName], attributePath + attributeName);
}
}
return attributePaths;
}
return attributePath;
} else {
}
}
}
return false;
}
}
return true;
}
function compareDevicePrintProfiles(attributeConfig, devicePrint, devicePrintProfiles, maxPenaltyPoints) {
var results = [];
var aggregatedComparisonResult = new ComparisonResult();
var comparisonResult;
if (storedValue === null) {
} else {
}
if (DEBUG.messageEnabled()) {
}
}
if (DEBUG.messageEnabled()) {
}
});
}
return null;
}
if (DEBUG.messageEnabled()) {
}
var selectedProfile = null;
if (DEBUG.messageEnabled()) {
}
}
if (selectedProfile === null) {
return false;
}
/* update profile */
var vals = [];
}
return true;
}
// Will fail this module but fall-through to next module. Which should be OTP.
} else if (compareDevicePrintProfiles(config.attributes, devicePrint, devicePrintProfiles, config.maxPenaltyPoints)) {
} else {
// Will fail this module but fall-through to next module. Which should be OTP.
}
}
}
//---------------------------------------------------------------------------//
// Unit Tests - DO NOT MODIFY //
//---------------------------------------------------------------------------//
getTestDetails = function() {
function getErrorObject() {
}
var err = getErrorObject();
// e.g. at shouldCreateComparisonResultWithZeroPenaltyPoints (eval at <anonymous> (eval at <anonymous> (http://repl.it/jsrepl/sandbox.js:39:104)), <anonymous>:247:73)
var callee_function = caller_line.slice(caller_line.indexOf("at ")+2, caller_line.indexOf("(eval"));
var callee_line_number = caller_line.slice(caller_line.indexOf("<anonymous>:")+12, caller_line.indexOf(":", caller_line.indexOf("<anonymous>:")+12));
};
var test_name_and_line_number = getTestDetails();
};
}
};
assertTrue = function(value) {
if (value !== true) {
logError("expected true");
}
};
assertFalse = function(value) {
if (value !== false) {
logError("expected false");
}
};
return;
}
return;
}
}
};
//DEBUG = {
// messageEnabled: function() { return true; },
// message: function(text) { console.log(text); }
//};
// ComparisonResult
function shouldCreateComparisonResultWithZeroPenaltyPoints() {
// Given
// When
var comparisonResult = new ComparisonResult();
// Then
}
// Given
// When
// Then
}
// Given
// When
// Then
}
function shouldCreateComparisonResultWithPenaltyPoints() {
// Given
// When
// Then
}
function shouldCreateComparisonResultWithAdditionalInfo() {
// Given
// When
var comparisonResult = new ComparisonResult(true);
// Then
}
function shouldAddComparisonResult() {
// Given
//When
//Then
}
function shouldGetComparisonResultSuccessful() {
//Given
//When
//Then
}
function shouldGetComparisonResultUnsuccessful() {
//Given
//When
//Then
}
function shouldCompareComparisonResultsEqually() {
//Given
//When
//Then
}
function shouldCompareComparisonResultsNotEqualPenaltyPoints() {
//Given
//When
//Then
}
//Given
//When
//Then
}
function shouldCompareComparisonResultsWithNull() {
//Given
var anotherComparisonResult = null;
//When
//Then
}
// ScalarComparator
function shouldCompareWithNoPenaltyPoints() {
//Given
var currentValue = "CURRENT_VALUE";
var storedValue = "STORED_VALUE";
//When
//Then
}
//Given
var currentValue = "CURRENT_VALUE";
var storedValue = "STORED_VALUE";
//When
//Then
}
//Given
var currentValue = null;
var storedValue = "STORED_VALUE";
//When
//Then
}
//Given
var currentValue = "CURRENT_VALUE";
var storedValue = null;
//When
//Then
}
// ScreenComparator
function shouldCompareScreensThatAreEqual() {
// Given
// When
// Then
}
function shouldCompareScreensThatAreNull() {
// Given
// When
// Then
}
function shouldCompareScreensWhenStoredScreenWidthIsNull() {
// Given
// When
// Then
}
// Given
// When
// Then
}
function shouldCompareScreensWhenStoredScreenHeightIsNull() {
// Given
// When
// Then
}
// Given
// When
// Then
}
// Given
// When
// Then
}
// Given
// When
// Then
}
// MultiValueComparator
//Given
var currentValue = "";
var storedValue = null;
//When
//Then
}
function shouldCompareMultiValueStringsWhenBothAreEmpty() {
//Given
var currentValue = "";
var storedValue = "";
//When
//Then
}
function shouldCompareMultiValueStringsWhenBothAreEqual() {
//Given
var currentValue = "VALUE_A; VALUE_B; VALUE_C; VALUE_D; VALUE_E";
var storedValue = "VALUE_A; VALUE_B; VALUE_C; VALUE_D; VALUE_E";
//When
//Then
}
//Given
var currentValue = "VALUE_AA; VALUE_B; VALUE_C; VALUE_D; VALUE_E";
var storedValue = "VALUE_B; VALUE_C; VALUE_D; VALUE_E";
//When
//Then
}
//Given
var currentValue = "VALUE_AA; VALUE_BB; VALUE_C; VALUE_D; VALUE_E";
var storedValue = "VALUE_B; VALUE_C; VALUE_D; VALUE_E";
//When
//Then
}
//Given
var currentValue = "VALUE_AA; VALUE_B; VALUE_C; VALUE_D; VALUE_E";
var storedValue = "VALUE_B; VALUE_C; VALUE_D; VALUE_E";
//When
//Then
}
//Given
var currentValue = "VALUE_AA; VALUE_BB; VALUE_C; VALUE_D; VALUE_E";
var storedValue = "VALUE_B; VALUE_C; VALUE_D; VALUE_E";
//When
//Then
}
// UserAgentComparator
function shouldCompareUserAgents() {
//Given
var currentValue = "USER_AGENT_1234567890.";
var storedValue = "1234USER_.567890AGENT_";
//When
//Then
}
function shouldCompareUserAgentsIgnoringVersionNumbers() {
//Given
var currentValue = "USER_AGENT_1234567890.";
var storedValue = "1234USER_.567890AGENT_";
//When
//Then
}
// GeolocationComparator
function shouldCompareLocationWhenBothXsAreNull() {
//Given
//When
//Then
}
function shouldCompareLocationWhenBothYsAreNull() {
//Given
//When
//Then
}
function shouldCompareLocationWhenCurrentXIsNull() {
//Given
//When
//Then
}
function shouldCompareLocationWhenCurrentYIsNull() {
//Given
//When
//Then
}
function shouldCompareLocationWhenStoredXIsNull() {
//Given
//When
//Then
}
function shouldCompareLocationWhenStoredYIsNull() {
//Given
//When
//Then
}
function shouldCompareLocationsThatAreEqual() {
//Given
//When
//Then
}
function shouldCompareLocationsThatAreWithinTolerableRange() {
//Given
//When
//Then
}
function shouldCompareLocationsThatAreOutsideTolerableRange() {
//Given
//When
//Then
}