Skip to content

Commit

Permalink
ability to compare the library's results with .NET (`node src\stringf…
Browse files Browse the repository at this point in the history
…ormat.tests.js dotnet`)
  • Loading branch information
thorn0 committed Aug 15, 2016
1 parent f536b44 commit 32575c8
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ bower_components/
node_modules/
tmp/
/build
*.exe
57 changes: 57 additions & 0 deletions checker/checker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma warning disable 0649

using System;
using System.Globalization;
using System.Text;
using System.Web.Script.Serialization;

class Arg
{
public string Format, Culture;
public object[] Args = new object[0];
}

class Result
{
public string ReturnValue, Format, Error;
}

public class Checker
{
static JavaScriptSerializer serializer = new JavaScriptSerializer();

static Result Process(string[] args) {
if (args == null || args.Length != 1) {
return new Result { Error = "Invalid argument" };
}
Arg arg;
try {
arg = serializer.Deserialize<Arg>(args[0]);
} catch {
return new Result { Error = "Invalid JSON: " + args[0] };
}
try {
var culture = arg.Culture == null ? CultureInfo.InvariantCulture : CultureInfo.GetCultureInfo(arg.Culture);
//System.Threading.Thread.CurrentThread.CurrentCulture = culture;
return new Result { ReturnValue = String.Format(culture, arg.Format, arg.Args), Format = arg.Format };
} catch (Exception e) {
return new Result { Error = e.Message };
}
}

public static void Main(string[] args) {
Console.WriteLine(UnicodeEscape(serializer.Serialize(Process(args))));
}

static string UnicodeEscape(string s) {
var sb = new StringBuilder();
foreach (var c in s) {
if (c > 127) {
sb.Append(String.Format(@"\u{0:X4}", Convert.ToInt32(c)));
} else {
sb.Append(c);
}
}
return sb.ToString();
}
}
63 changes: 63 additions & 0 deletions checker/checker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*jshint undef:true, node:true*/
/*global sffjs*/
"use strict";

var child_process = require('child_process'),
path = require('path'),
fs = require('fs');

var exe = path.join(__dirname, 'checker.exe'),
src = path.join(__dirname, 'checker.cs');

if (!fs.existsSync(exe)) {
child_process.execSync('csc /out:' + JSON.stringify(exe) + ' ' + JSON.stringify(src), { encoding: 'utf8' });
}
if (!fs.existsSync(exe)) {
throw new Error('Can\'t find checker.exe');
}

module.exports = function() {
var arg = {
format: arguments[0],
args: Array.prototype.slice.call(arguments, 1),
culture: sffjs.LC.name || undefined
};
var resultJson = child_process.execFileSync(exe, [stringifyJsonCommandLineArgument(arg)], { encoding: 'utf8' });
var result = JSON.parse(resultJson);
if (result.Error) {
throw new Error(result.Error);
} else if (arg.format !== result.Format) {
throw new Error('Format string got corrupted "' + arg.format + '" -> "' + result.Format + '"');
} else {
return result.ReturnValue;
}
};

function padWithLeadingZeros(string) {
return new Array(5 - string.length).join("0") + string;
}

function unicodeCharEscape(charCode) {
return "\\u" + padWithLeadingZeros(charCode.toString(16));
}

function unicodeEscape(string) {
return string.split("")
.map(function(char) {
var charCode = char.charCodeAt(0);
return charCode > 127 ? unicodeCharEscape(charCode) : char;
})
.join("");
}

function stringifyJsonCommandLineArgument(arg) {
var originalPrototypeDateToJSON = Date.prototype.toJSON;
Date.prototype.toJSON = function() {
return '/Date(' + (this.valueOf() - this.getTimezoneOffset() * 60000) + ')/'; // FIXME
};
var argJson = unicodeEscape(JSON.stringify(arg))
.replace(/(\/Date\(\d+\))\//g, '\\$1\\/')
.replace(/\\\\/g, '\\u005c');
Date.prototype.toJSON = originalPrototypeDateToJSON;
return argJson;
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"load-grunt-tasks": "^3.5.2"
},
"scripts": {
"test": "node src/stringformat.tests"
"test": "node src/stringformat.tests",
"dotnet": "node src/stringformat.tests dotnet"
}
}
32 changes: 27 additions & 5 deletions src/stringformat.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,33 @@
*
*/
/*jshint -W045:true, undef:true, browser:true, node:true*/
/*global sffjs,require*/
/*global sffjs*/
(function() {
"use strict";
var browser = typeof window !== 'undefined';
var browser = typeof window !== 'undefined',
dotNetStringFormat;

if (!browser) {
global.sffjs = require('./stringformat');
require('./cultures/stringformat.en-US');
require('./cultures/stringformat.sv');
require('./cultures/stringformat.uk');
sffjs.unsafe();

if (process.platform === 'win32' && process.argv[2] === 'dotnet') {
dotNetStringFormat = require('../checker/checker');
}
}

/// <summary>
/// Performs a series of unit tests and writes the output to the page.
/// </summary>

function runTests(test) {
sffjs.setCulture("en");
if (browser) {
// In the browser, sffjs tries to get the culture from the properties of the navigator object
sffjs.setCulture('en');
}

var testObject = {
a: "b",
Expand Down Expand Up @@ -540,8 +548,6 @@
};

this.printInNonBrowserEnv = function() {
console.log(String.format("{0} of {1} tests passed", this.numPassedTests, this.numTests));

for (var si in t.sections) {
var section = t.sections[si];
var sectionNamePrinted = false;
Expand All @@ -559,6 +565,7 @@
console.log();
}
}
console.log(String.format("{0} of {1} tests passed", this.numPassedTests, this.numTests));
};
}

Expand Down Expand Up @@ -649,6 +656,21 @@
return;
}

if (dotNetStringFormat) {
var dotNetActual;
try {
dotNetActual = dotNetStringFormat.apply(null, args);
} catch (e) {
registerTestResult(message, ".NET: " + e);
return;
}
var sameResult = dotNetActual === actual;
if (!sameResult) {
registerTestResult(message, String.format(".NET: {0}, actual: {1}", stringify(dotNetActual), stringify(actual)));
return;
}
}

message = String.format("{0,-25} {1}", formatString, actual);

assert.areEqual(expected, actual, message);
Expand Down

0 comments on commit 32575c8

Please sign in to comment.