cancel
Showing results for 
Search instead for 
Did you mean: 

Boolean or not ?

SOLVED
BenoitB
Community Hero

Boolean or not ?

We have the need to set/get boolean value on components where sometimes property, or test data is not a boolean.

 

Please share and discuss about your best way to determine if a value is a boolean.

 

Mine is below.

 

 

/**
 * <a id="stringToBoolean"></a>
 * Renvoie le type boolean true ou false selon la chaîne en entrée :<br>
 * - "true", "yes", "on", "1", "oui", "vrai", "checked" renvoie true<br>
 * - "false", "no", "off", "0", "non", "faux", "unchecked", "", null renvoie false<br>
 * - autres valeurs, essaye de convertir en String pour l'évaluer, le cas échéant renvoie false
 * @function
 *  {string} [value=""] - Chaîne à convertir
 * @returns {boolean} Renvoie <b>true</b> ou <b>false</b>
 */
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 "0" : 
    case "off" :
    case "" :
    case "non" :
    case "faux" :
    case "unchecked" :
    case null : 
      return false;
    default: 
      return Boolean(value);
  }
}

 

 

Un sourire et ça repart

2 ACCEPTED SOLUTIONS

Accepted Solutions
BenoitB
Community Hero

Re: Boolean or not ?

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

Un sourire et ça repart

View solution in original post

AlexKaras
Community Hero

Re: Boolean or not ?

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.)

 

Regards,
  /Alex [Community Hero]
____
[Community Heroes] are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Posts made by [Community Heroes]
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
The [Community Hero] signature is used with permission by SmartBear Software.
https://community.smartbear.com/t5/custom/page/page-id/hall-of-fame
================================

View solution in original post

10 REPLIES 10
Marsha_R
Community Hero

Re: Boolean or not ?

BenoitB
Community Hero

Re: Boolean or not ?

Yes i was aware of that method but not answering my needs, perhaps i didn't explained them clearly.

 

The main goal is to let user to use their standard definition of what is on or off, that could be a 0 and 1, or a true and false, or 'checked' and 'unchecked', or 'on' and 'off' , or '1' and null ...

 

.. And moreover aqConvert is an heavy one ..

 

 

 

Un sourire et ça repart

AlexKaras
Community Hero

Re: Boolean or not ?

Hi,

 

I used practically the same but regex-based:

  return aqObject.CompareProperty(aqString.ToLower(aqConvert.VarToStr(aValue)), cmpMatches, "^(true)|(yes)|(t)|(y)|([1-9])$", false, lmNone);

 

Regards,
  /Alex [Community Hero]
____
[Community Heroes] are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Posts made by [Community Heroes]
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
The [Community Hero] signature is used with permission by SmartBear Software.
https://community.smartbear.com/t5/custom/page/page-id/hall-of-fame
================================
BenoitB
Community Hero

Re: Boolean or not ?

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

Un sourire et ça repart

View solution in original post

BenoitB
Community Hero

Re: Boolean or not ?

No other idea ?

A true challenge to find a "good" code for this  😀

Un sourire et ça repart

Marsha_R
Community Hero

Re: Boolean or not ?

If you want me to find a better way, then first you have to find my spare time to do it in.  🙂   

 

No spare time = take the first thing that works pretty well and use that   

tphillips
Community Leader

Re: Boolean or not ?

The way I would do it would be to define a list of true values and a list of false values.

Then check to see if the user input is in one of those lists.

 

Unless I am misunderstanding the original problem?


--------------------
QA Systems Architect
BenoitB
Community Hero

Re: Boolean or not ?

Yes this is the way we've discussed but the point, as a challenge, is to find the faster, less dependant on TC objects and elegant way of doing it.

As for now :

The most elegant, IMHO, was @AlexKaras way but it's dependant on TC objects and slow.

The faster and less dependant was mine.

 

If you have any idea you're welcome !

 

 

Un sourire et ça repart

AlexKaras
Community Hero

Re: Boolean or not ?

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.)

 

Regards,
  /Alex [Community Hero]
____
[Community Heroes] are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Posts made by [Community Heroes]
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
The [Community Hero] signature is used with permission by SmartBear Software.
https://community.smartbear.com/t5/custom/page/page-id/hall-of-fame
================================

View solution in original post

New Here?
Join us and watch the welcome video:
Announcements