Boolean or not ?
- 4 years ago
Nice idea AlexKaras , but you can remove your aqString.ToLower as you compare in case-insensitve mode.
So i make a simple benchmark with following code :
function stringToBoolean (value = "") { if (typeof value != 'string') { try { value = value.toString(); } catch(e) { value = ""; } } switch(value.toLowerCase().trim()){ case "true" : case "yes" : case "on" : case "1" : case "oui" : case "vrai" : case "checked" : return true; case "false" : case "no" : case "-1" : case "0" : case "off" : case "" : case "non" : case "faux" : case "unchecked" : case null : return false; default: return Boolean(value); } } function TestBool(aValue) { Log.Message("Value = " + aValue); aqPerformance.Start("DefaultCounter", false); try { Log.Message("Alex = " + aqObject.CompareProperty(aqString.ToLower(aqConvert.VarToStr(aValue)), cmpMatches, "^(true)|(yes)|(t)|(y)|([1-9])$", false, lmNone)); } catch(e) { Log.Message("Alex, exception : " + e.message) }; Log.Message("Perf Alex = " + aqPerformance.Value()); aqPerformance.Start("DefaultCounter", false); try { Log.Message("Alex simple = " + aqObject.CompareProperty(aqConvert.VarToStr(aValue), cmpMatches, "^(true)|(yes)|(t)|(y)|([1-9])$", false, lmNone)); } catch(e) { Log.Message("Alex simple, exception : " + e.message) }; Log.Message("Perf Alex simple = " + aqPerformance.Value()); aqPerformance.Start("DefaultCounter", false); Log.Message("Bibi = " + stringToBoolean(aValue)); Log.Message("Perf Bibi = " + aqPerformance.Value()); } TestBool(true); TestBool(false); TestBool("true"); TestBool("false"); TestBool("yes"); TestBool("no"); TestBool(null); TestBool(); TestBool(-1); TestBool(0); TestBool(1); TestBool(1.0); TestBool(NaN); TestBool({obj : 1}); TestBool([1]);
The result are :
- on simple type, same results 😀
- method with aqConvert is very slow 😆
- on table/objetct type, different results, mine return "true", yours "false" 😔
In conclusion i will stay with mine because of speed and less dependant of TestComplete.
But i admit that your method is by concept a nice one !
- detailled results below :
Value = true
Alex = true Perf = 13
Alex2 = true Perf Alex2 = 7
Bibi = true Perf Bibi = 2
Value = false
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 2
Value = true
Alex = true Perf Alex = 9
Alex2 = true Perf Alex2 = 7
Bibi = true Perf Bibi = 2
Value = false
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 2
Value = yes
Alex = true Perf Alex = 9
Alex2 = true Perf Alex2 = 7
Bibi = true Perf Bibi = 2
Value = no
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 7
Value = null
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 2
Value = undefined
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 2
Value = -1
Alex = false Perf Alex = 8
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 2
Value = 0
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = false Perf Bibi = 2
Value = 1
Alex = true Perf Alex = 8
Alex2 = true Perf Alex2 = 7
Bibi = true Perf Bibi = 2
Value = 1
Alex = true Perf Alex = 9
Alex2 = true Perf Alex2 = 7
Bibi = true Perf Bibi = 2
Value = NaN
Alex = false Perf Alex = 9
Alex2 = false Perf Alex2 = 7
Bibi = true Perf Bibi = 2
Value = [object Object]
Alex = false Perf Alex = 11
Alex2 = false Perf Alex2 = 9
Bibi = true Perf Bibi = 2
Value = 1
Alex = true Perf Alex = 11
Alex2 = true Perf Alex2 = 9
Bibi = true Perf Bibi = 2 - 4 years ago
Hi Benoit,
Your idea with performance measuring is really a great one. I thought about it after I wrote my initial reply to this thread but did not try it yet. 😞
One more idea:
Instead of
switch(value.toLowerCase().trim()){ case "true" : case "yes" : case "on" : case "1" : case "oui" : case "vrai" : case "checked" : return true;
which uses several 'case'-s without return (I understand the reason but I bet you know;) that this is not recommended technique), you may consider this:
var strTrueList = 'true|yes|on|1|oui|vrai|checked'; var strFalseList = 'false|no|off|0|non|faux|unchecked|'; // explicit null is not supported switch (true) case aqObject.CompareProperty(value.trim(), cmpIn, strTrueList, false, lmNone) : return true; case aqObject.CompareProperty(value.trim(), cmpIn, strFalseList, false, lmNone) : return false; default: return Boolean(value); // or just var strTrueList = 'true|yes|on|1|oui|vrai|checked'; if (aqObject.CompareProperty(value.trim(), cmpIn, strTrueList, false, lmNone)) return true; else return false;
(Though not sure if it is faster than native JScript code.)
P.S.
> less dependant on TC objects
My personal preference is opposite: if some TC object provides functionality that I need then I will use this object in favor of the native functionality provided by the scripting language that is used for the project.
The reason for this is that it is much more easy to port the code that uses TC objects between projects based on different scripting languages.
Sure, if one is an employee for the project that lasts for many years, the above might be irrelevant for him/her. But if one works, say, as a contractor/consultant, then the use of TC objects makes it faster and with less chance of an error to move generic/library test code between different projects.
P.P.S.
> - on table/objetct type, different results, mine return "true", yours "false" 😔
I tried to evaluate
Boolean({obj : 1})
and
Boolean({obj : 0})
in TestComplete's Evaluate dialog. Result in both cases was True which makes me think that in your case True was returned not because obj property was set to 1, but because the whole argument for the Boolean() function was not null/empty and thus was evaluated to boolean True. (The same relates to the NaN argument.)