How to get LOCALE_SNAME using JScript in TestComplete? - locale

Using JScript in TestComplete, how do I retrieve the locale name?
Should I use GetLocaleInfo or GetLocaleInfoEx?
It looks like the LOCALE_SNAME constant is not defined in TestComplete. What value should I pass instead?
I tried this code:
function GetTimeSettings()
{
var rrr = Win32API.GetUserDefaultLCID();
LOCALE_SNAME = rrr;
Log.Message("Locale Name: " + GetLocaleInfoEx(LOCALE_USER_DEFAULT, LOCALE_SNAME));
}
but it throws the "Object expected" error.

Use aqEnvironment.GetLocaleInfo, or just GetLocaleInfo for short. It's a wrapper for the Windows API function GetLocaleInfo.
The LOCALE_SNAME constant isn't defined in TestComplete; you need to define it manually:
var LOCALE_SNAME = 0x0000005c;
Log.Message(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNAME));

Related

populate object properties using lambda expression in typescript

Newbie Alert! I feel silly asking this question but I need someone to teach me the correct syntax.
I have code that looks like this:
let thing: INewThing;
thing.personId = another.personId;
thing.address = another.work.address;
thing.greades = another.subjectInfo.grades;
thing.isCurrent = another.student.isCurrent;
I know it can be written cleaner. I want to use a lamda expression, something like this:
let thing: INewThing => {
personId = another.personId,
address = another.work.address,
grades = another.subjectInfo.grades,
isCurrent = another.student.isCurrent
} as IThingUpdate;
I have looked and looked for an example. I have yet to find one that works for me. It's just syntax but no matter what I try it doesn't work.
You're just looking to create a new object, which is a pretty different thing from a "lambda" (function). Just declare the object. You don't need a function.
const thing = {
personId: another.personId,
address: another.work.address,
// use the correct spelling below - no 'greades'
grades: another.subjectInfo.grades,
isCurrent: another.student.isCurrent,
};
If the another is typed properly, that should be sufficient.
If the another object had more properties using the same path, another option would be to destructure those properties out, then declare the object with shorthand, eg:
const originalObj = { prop: 'val', nested: { foo: 'foo', bar: 'bar', unwanted: 'unwanted' } };
const { foo, bar } = originalObj.nested;
const thing = { foo, bar };
Destructuring like this, without putting the values into differently-named properties, helps reduce typos - if a property starts out, for example, as someLongPropertyName, putting it into a standalone identifier someLongPropertyName and then constructing an object with shorthand syntax ensures that the new object also has the exact property name someLongPropertyName (and not, for example, someLongPRopertyName - which isn't that uncommon of a mistake when using the more traditional object declaration format).
But since all the paths in your another object are different, this approach wouldn't work well in this particular situation.

Getting a Fail Trying to Parse a ZonedDateTime from a String Using ZonedDateTimePattern

I've been learning how to use NodaTime, as I think it is a far superior "all things temporal" library that the handful of structs in the BCL. Reading the docs and experimenting.
This experiment has me flummoxed. I started out just trying to parse a ZonedDateTime.
The things I was trying were not successful, so I thought I'd try something which should be "bulletproof". The following code represents that attempt:
Instant thisNow = SystemClock.Instance.GetCurrentInstant();
var timezone = DateTimeZoneProviders.Tzdb["Australia/Brisbane"];
var zonedDateTime = thisNow.InZone(timezone);
var zonePattern = ZonedDateTimePattern.GeneralFormatOnlyIso;
var zoneFormatted = zonePattern.Format(zonedDateTime);
var zoneParseResult = zonePattern.Parse(zoneFormatted);
Console.WriteLine(zoneParseResult.Success ? "parse success" : "parse failure");
So, simply trying to parse back that which you just converted to a string.
The zoneFormatted has the following value 2021-09-04T16:59:08 Australia/Brisbane (+10)
Any ideas what I am doing wrong?
Cheers
Any ideas what I am doing wrong?
You're using ZonedDateTimePattern.GeneralFormatOnlyIso, which is (as the name suggests) only for formatting, not for parsing.
To get a pattern which is able to parse time zones, you need to specify an IDateTimeZoneProvider. The easiest way to do that is to start with a format-only pattern, and use WithZoneProvider:
using NodaTime;
using NodaTime.Text;
using System;
class Program
{
static void Main(string[] args)
{
var pattern = ZonedDateTimePattern.GeneralFormatOnlyIso
.WithZoneProvider(DateTimeZoneProviders.Tzdb);
var text = "2021-09-04T16:59:08 Australia/Brisbane (+10)";
var result = pattern.Parse(text);
Console.WriteLine(result.Success);
Console.WriteLine(result.Value);
}
}

Calling function with callback defined as string

var method = 'serviceName.MethodName'
I Just want to call it like
serviceName.methodName(function(output callback){
});
Is there any approach to call it.thanks
There are two methods that I can think of now.
JS eval
You can use the javascript eval function to convert any string into code snippet like below. Although eval is a quick solution but should not be used unless you dont have any other option by your side.
var method = 'UserService.getData';
eval(method)();
Factory pattern
Use a below pattern to get the service
You would need to define the services in such a manner that you can access them using a pattern.
var Services = {
// UserService and AccountsService are again objects having some callable functions.
UserService : {getData: function(){}, getAge: function(){}},
AccountsService : {getData: function(){}, getAge: function(){}},
// getService is the heart of the code which will get you the required service depending on the string paramter you pass.
getService : function(serviceName){
var service = '';
switch(serviceName){
case 'User':
service = this.UserService;
break;
case 'Accounts':
service = this.AccountsService;
break;
}
return service;
}
}
You can use get the required service with below code
Services.getService('User')
I'm not aware of any way you can resolve the serviceName part of that string to an object, without using eval. So obviously you need to be extremely careful.
Perhaps:
if (method.match(/^[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+$/) {
var servicePart = eval(method.split('.')[0]);
var methodPart = method.split('.')[1];
servicePart[methodPart](...)
}
There are two separate problems in your question:
How to access object property by property name (string)?
How to access object by it's name (string)?
Regarding the first problem - it is easy to access object property by string using the following notation:
const myObject = {
myProp: 1,
};
console.log(myObject['myProp']);
And regarding the second problem - it depends on what serviceName is:
if it is a property of some other object, then use someObject['serviceName']['MethodName']
if it is a local variable, consider using a Map (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) to associate strings with objects;

Javascript named function expression, reference error

I am getting "Reference Error" very randomly (about once in 200 attempts ) with the following code.
var securityPrototype = {
init: function(){ /* ... */ },
encryptionKey: function x() {
var i = x.identifier;
return getKey(i);
}
}
securityPrototype.encryptionKey.identifier = Date.now();
function Security(){}
Security.prototype = securityPrototype;
Security.constructor = Security;
function getKey(){ /* ... */ }
var gate = new Security()
gate.encryptionKey(); // Randomly throws : ReferenceError: x is not defined
This code segment lives inside other code but no "eval" is being used , neither the 'with' operator.
I am trying to figure out if due to any condition it is possible to get this error here.
Browser that reproduces this: Chrome on Mac and Windows.
IE and Safari work fine.
That's because a bug in the implementation of named function expressions, that exists in some versions of some browsers.
In those browsers, two separate function objects are created when you use a named function expression. The property gate.encryptionKey is a reference to one function object, and the name x is a reference to a different function object. They both contain the same code, but they are different instances of the Function class.
When you assign a value to gate.encryptionKey.identifier, that property is only available in the function object that gate.encryptionKey references. The function object that x references doesn't have that property.
Simple example of the behaviour in those browsers:
var f = function g(){};
f === g; // false
f.expando = 'foo';
g.expando; // undefined
This example (example #3) was taken from the page Named function expressions demystified, where you can read more about named function expressions, and the implementation bugs.

Accessing object value in knockout

I declare this in knockout:
self.quizAnswer = ko.observableArray([{val: ko.observable()}]);
I can push the value there:
self.quizAnswer.push({ val: ko.observable('new') });
But tell me please how to easily read/rewrite the value like:
self.quizAnswer()[#position#].val = "new value";
I tried almost everything, but I dont know.
Thank you very much!!!
Because observable is function, you should invoke it without parameter to read its value:
self.quizAnswer()[0].val();
or with parameter to set new value:
self.quizAnswer()[0].val("new value");
Another option is to use knockout-es5 plugin. If you use this plugin you can invoke something like this:
ko.track(self.quizAnswer()[0]);
and after that you can access all observable of "tracked" objects like regular fields:
self.quizAnswer()[0].val = "new value"

Resources