Javascript date test harness - javascript

I have written my own implementation of Date() in Javascript, BardyDate, which in addition to all the properties/methods of Date, does a bunch of other stuff. Why I have done this is a very good question indeed but it is such a long story I will save it for a rainy day.
But what I was thinking would be lovely would be to be able to verify that it still behaves correctly as a Date. I know nothing about test suites etc but wondered how I might apply any existing tests for the Javascript Date object to my BardyDate to show correctness?
Any advice very welcome.

I waited to respond because I am not certain that there are no Date test suites already out there for javascript. I wanted to give the benefit of the doubt to anyone who might know more.
However, as far as I know this sort of testing would all be done in browser building/validation. It certainly is possible to use some of the existing test suites from that realm of development, but I don't think it would be an easy task to set-up. Many of the browser's have a build process that you could fork (specifically you could isolate their date test cases). Within their test process you would have to find the given segment for Javascript Date objects, that would test to ensure w3 spec compatibility.
At that, Selenium is a very common and practical means of creating unit tests and if designed well integration tests for web-apps (hooking into the javascript as well), and is capable of producing nice reports on test results.
Lastly, a cummulative post on Javascript Testing libraries can be found on this post about Javascript TDD (Test Driven Design)
Or you could do something like the following (meant to be a guideline not a complete solution -- inspired by the comment from dandavis):
var epochTS = 0;
var bd = new BardyDate(epochTS);
var d = new Date(epochTS);
Object.getOwnPropertyNames(Date.prototype).forEach(function(dateFunction){
//in this if statement you are testing the functions like getTime() and getYear()
if(dateFunction.indexOf("get") == 0){
console.log("dateFunction " + dateFunction +
"() pass: " + (bd[dateFunction]() === d[dateFunction]()))
}
//in this if statement you are testing the functions like toString() and toJSON()
if(dateFunction.indexOf("to") == 0){
console.log("dateFunction " + dateFunction +
"() pass: " + (bd[dateFunction]() === d[dateFunction]()))
}
//then there are the 16 set methods, those you probably would want to hardcode.
//unless you are content with passing a hard coded value in like "10" -- the
//issue would be bounds testing, which you would likely want to hardcode.
//beyond the scope of this for-each loop.
})
A little explanation on the above snippet
With Object.getOwnPropertNames(Date.prototype) you can obtain all the methods of Date despite the fact that Date has the property DontEnum (see this post for more info).
Also you are able to treat each function string as a key within the javascript object hence the d[dateFunction]() which if dateFunction === "toString" would be interpreted/compiled down to d[toString]() which is equivalent to d.toString()

Related

How to add 30 minutes to startdate in update/delete dialog in fullcalendar 3.10 javascript

In the update window I would like to automatically add 30 minutes to the event start date:
$('#updatedialog').dialog({
autoOpen: false,
width: 680,
buttons: {
"update": function () {
var eventToUpdate = {
id: currentUpdateEvent.id,
title: $("#eventName").val(),
description: $("#eventDesc").val(),
color: $("#colorPicker").val(),
start: new Date($("#eventStart").val()),
end: new Date($("#eventEnd").val()),
//end: new Date($("#eventEnd").val(moment(event.start).add(30, "m").format("YYYY-MM-DD[T]HH:mm"))),
//end: new Date($("#eventEnd")).setMinutes($("#eventStart").val() +30),
note: $("#EditEventNote").val(),
/*start: moment($("#eventStart").val(), "DD/MM/YYYY HH:mm"),*/
};
PageMethods.UpdateEvent(eventToUpdate, updateSuccess);
$(this).dialog("close");
currentUpdateEvent.title = $("#eventName").val();
currentUpdateEvent.description = $("#eventDesc").val();
currentUpdateEvent.color = $("#colorPicker").val();
currentUpdateEvent.note = $("#EditEventNote").val();
currentUpdateEvent.start = new Date($("#eventStart").val());
currentUpdateEvent.start.setMinutes(currentUpdateEvent.start.getMinutes() + 30);
$('#calendar').fullCalendar('updateEvent', currentUpdateEvent);
$('#calendar').fullCalendar('refetchEvents');
},
But this code doesn't work.
Firstly this is largely a momentJS issue, not a fullCalendar one.
You need to clone the start date, mutate it by 30 minutes, and then format it for output.
N.B. event.start doesn't actually appear anywhere in your code, so I'm assuming you actually wanted to use the value from the "eventStart" textbox instead. And I've gone back to setting the date format the way we agreed in your earlier question about this code. It's unclear why you've stopped doing it that way, because you already made clear it didn't work to set the start/end dates using new Date(...).
Therefore your code would look this like:
"update": function () {
var start = moment($("#eventStart").val()); //parse the start date
var end = moment(start); //clone the start date to make the end date
end.add(30, "m"); //add 30 minutes to the end date
//create the event object with formatted dates
var eventToUpdate = {
start: start.format("YYYY-MM-DD HH:mm"),
end: end.format("YYYY-MM-DD HH:mm")
//...etc
};
$("#eventEnd").val(end.format("YYYY-MM-DD[T]HH:mm")); //only include this line if you actually want to set the value of the eventEnd textbox.
//...etc
Minimal demo: https://codepen.io/ADyson82/pen/PojKGXY
Relevant documentation:
https://momentjs.com/docs/#/parsing/moment-clone/
https://momentjs.com/docs/#/manipulating/add/
P.S. I want to make a more general point about your approach to programming, based on what you've shown here, and your various previous questions where I've intervened.
This attempt:
//end: new Date($("#eventEnd").val(moment(event.start).add(30, "m").format("YYYY-MM-DD[T]HH:mm")))
contains a jumble of code all packed together in what appears to be a giant piece of guesswork, or possibly a "throw everything at it until something sticks" approach. Neither of those techniques are going to make you a good programmer. Programming is a science / engineering discipline, not an art form or a hit-and-hope game. You need to be methodical and precise. If the best you can say about it is that it "doesn't work", then it's clear you haven't analysed it at all. To solve problems in your code, you need to analyse it and debug it piece by piece.
So what you need to do with that code, to see why it's not working, is take it all apart, read the documentation properly for each of the many functions you've used there, and work out what they output and whether that's relevant to your situation - and/or whether each one gives suitable input to the thing you've included it within.
When testing JavaScript / jQuery code you should also be checking in your browser's Console (in the Developer Tools) for errors, and using the built-in debugger to step through the code line by line to see the values of your variables, and spot where the code and the values don't do what you expected them to. (If you don't know what you expect a particular part of the code to do, then you should either scrap that part and write something you can understand, or go and read documentation and try examples using that code until you do understand it. Otherwise you're just back to guessing again, and that's pointless.)
You can test each part of the code individually to verify your understanding. Putting large numbers of function calls together in one line like in the example above makes it very difficult to debug - for testing, you should split it into invidiual lines and see what each one produces, before deciding whether it's useful to put into the next step. For example if we break down that code into separate steps, we'd end up with:
var moment1 = moment(event.start);
moment1.add("30", "m");
var formattedDate = moment1.format("YYYY-MM-DD[T]HH:mm");
var x = $("eventEnd").val(formattedDate);
var dt = new Date(x);
var eventToUpdate = {
//...
end: dt
}
Now let's pick apart the logical flaws, one by one:
event.start doesn't appear to exist in the context you've shown (unless you've omitted some outer code). So you're probably starting with a blank to begin with. As I mentioned above, I'm guessing you actually meant to use the value from the eventStart textbox instead.
If event.start does exist in this context, then it looks like it probably came from fullCalendar, and fullCalendar v3 (as per its documentation) already gives you dates as momentJS objects - so you don't need to wrap them in the moment() constructor all over again. Whilst it does no harm, it's also inefficient and clutters up your code for no reason.
$("eventEnd").val() will set the value of a field on the page. It's not clear whether this was intentional or not, since your stated objective was to add 30 minutes to the event's start date (presumably to form an end date ready to send to the server, although your wording could be interpreted to mean you actually want to modify the start date itself, not use it as an end date).
.val() doesn't return a value (it only sets a value when used the way you've done it). Therefore x will always be empty.
Because x is empty, new Date(x) won't do anything useful.
You don't want new Date anyway, because you need to send a pre-formatted Date as a string to your server - we already discussed this in one of your previous questions so it's not clear why you've tried this again now - apart from, as I've assumed above - that you still don't really understand any of these individual pieces of code and are still guessing randomly without testing them properly or reading anything about what they do. I will speak candidly and say that you will never achieve anything as a programmer until you learn to do both of those things. Once you start doing them, your tasks will suddenly start to seem a lot easier.
As you can see, once we break this down one by one, it's a lot easier to find the problems on their own than when it's all together in one line and you can't tell which part is doing what. Once you've got something that works, then it's fine to reduce it down into less lines if you think it saves space or makes the code neater. But don't do that until you're sure it's going to do what you want.

How does mongodb create database/collection on the fly

Mongodb is cool enough to create the database/collection on the fly, if we run a code similar to
db.store.save({a: 789});
It automatically creates store collection and add a document to it.
My javascript understanding says it is not possible to call a method on an undefined property of db object. It should have resulted in some kind of error/exception.
I am curious to understand the happenings behind the scene and if there is any helpful link please point me to those. Googling did not help me much.
In JavaScript there is a way to define a function that will be executed when an undefined method is called.
Example:
var o = {
__noSuchMethod__: function(id, args) { console.log(id, '(' + args.join(', ') + ')'); }
};
o.foo(1, 2, 3);
o.bar(4, 5);
o.baz();
// Output
// foo (1, 2, 3)
// bar (4, 5)
// baz ()
Note this is a non-standard feature and today only works in Firefox.
I do not know how MongoDB implemented this feature, but I'm just responding in order to report that can be done this way.
Fot more details see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/noSuchMethod
As I recall in a NodeJS environment you must do something like this to actually create a record: db.get('collectionName').insert({..something...}); or db.get('collectionName').save({...something...}); but you don't get to use the collection name as a property of db.
The line you're mentioning is only used in MongoDB shell, which is not Javascript.
I guess you're misunderstanding what's MongoDB shell and what's a MongoDB driver.
So long story short MongoDB (driver) is not able to access an undefined property.
EDIT
In response to your comment..
MongoDB JS driver's GitHub page pretty much points out how to insert a field and always uses the syntax I mentioned: https://github.com/mongodb/node-mongodb-native
As for what you're using in the shell it's pretty clear that you can't just use Javascript in a command shell. So I guess I'll point you to a place in which you can see in what language was MongoDB developed: http://www.mongodb.org/ pretty much the first line says it's written in C++.
Hope this helps clarify your question

Find all string variables in javascript files

i am facing the problem that i have to translate a larger html and javascript project into several languages. The html content was no problem, but the numerous javascript files are problematic, since i was a bit lazy during the development process. For instance, if i needed a message text, i just added it in the concerning position.
My approach now is, that i am using a build-in file search (Eclipse) for every occurrence of " and ', which i am getting line-wise. This would be extremely time consuming and errors are unavoidable.
Here are some examples that occur in the files:
var d = "Datum: " + d.getDate()+"."+(d.getMonth()+1)+"."+d.getFullYear();
showYesNoDialog("heading text","Are you sure?",function(){};
Sometimes i am mixing " and ', sometimes a string goes over several lines:
var list="";
list+='<li data-role="list-divider">';
list+='Text To Translate';
list+='</li>';
Things i don't want to get, are jquery selectors, e.g.:
$("input[name^=checkbox]").each(function () {};
Do you see any time saving method to get all of the strings that i would like to translate?
Regex? A java interpreter? Grep?
I know, that is a bit unusual question.
So any suggestion would be great.
Thanks in advance!
It is better to use some kind of the lexical scanner that converts the code into the tokens and then walk over the list of tokens (or syntax tree). There is a number of such tools (I even created one of them myself - here you can find some of the examples https://github.com/AlexAtNet/spelljs/blob/master/test/scan.js).
With it you can scan the JS file and just iterate over the tokens:
var scan = require('./..../scan.js');
scan(text).forEach(function (item) {
if (item.str) {
console.log(item);
}
});

How to create a datetime object in javascript when using javascript remoteTK/remote toolkit

I am new to salesforce and I know my question sounds silly. But I need someone to tell me the direction I should go.
My question is how can I convert string or object like this
{Start_time__C:"2014-07-24T20:55:00.000+0000"}
and this
{perDiem: true}
into salesforce object. And then I can use create function in remoteTK.
I am currently building custom app on salesforce1. In my visualforce page, I need to create new record, which has datetime, and boolean as its fields.
Thank you in advance!
I don't know much about the remoteTK but before you deep dive into it you might want to look into the "Remote Objects" from Spring'14. This seems to be the new hip / official way of doing remoting (which doesn't mean I'm saying rTK is bad!) and slightly easier to use.
https://salesforce.stackexchange.com/questions/33072/visualforce-remote-objects
https://developer.salesforce.com/blogs/developer-relations/2014/03/spring-14-using-visualforce-remote-objects-with-canjs.html
http://andyinthecloud.com/2014/01/22/spring14-visualforce-remote-objects-introduction/
http://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects_example_extended.htm
The main difference between them seems to be that you could use rTK in a non-visualforce page as underneath it just relies on REST callouts. The remote objects use a special VF tag so it's VF-only.
In the end I think it won't matter much which library you'll use. Sample remote object code:
// Create work order line item
var workOrderLineItem = new SObjectModel.WorkOrderLineItem__c();
workOrderLineItem.set('Description__c', 'Answering the question');
workOrderLineItem.set('Hours__c', answer);
workOrderLineItem.set('WorkOrder__c', result[0]);
workOrderLineItem.create(function(error, result, event)
{
// Errors?
if(error!=null)
alert(error);
else
alert('Success');
});
vs. the sample from remoteTK:
var objectType = 'Account';
var fields = {'Name': 'salesforce.com', 'Description':'CRM'};
client.create(objectType , fields,
function(response) {
getAccounts(function() {
$j.mobile.pageLoading(true);
$j.mobile.changePage('#mainpage', "slide", true, true);
});
}, errorCallback);
So a JavaScript object with fields is being created in both cases. For Booleans you should be good sending 'true' or 'false' strings.
For dates you might have to experiment a bit. Generally I've been passing Unix timestamp (miliseconds since Jan 1 1970), this seemed to work OK for me in REST calls or Visualforce Remoting (by which I mean #RemoteAction stuff, yet another tool).
The RemoteTKController.writeFields() seems to be using Date.valueOf(someString) when casting. This means the format should be 'yyyy-MM-dd HH:mm:ss' which is close enough - check if it will work out of the box and remove the timezone part from your string if it causes problems? You could simplify your examples a lot by skipping the remote part and directly check in Developer Console or Execute Anonymous how the parser reacts to different dates you'll feed it.
There's another function that seems to use REST API instead of the controller. This one will just pass the payload to REST API's POST request. Looking at how it's built you should be fine just passing a real JavaScript Date object as value, the JSON.stringify call should figure out how to serialize that. If you really want to craft the string yourself - check the REST API guide. The dates should look like that and all remoteTK'create call does is make a request similar to this one
This is an old thread, but in case it helps someone I was able to get this working. The yyyy-MM-dd HH:mm:ss format was very close. All it needed was a 'T' between the date and time to be acceptable. From there is was just making sure that all components came through as two digits, and converting the date to UTC time. Here's my final Javascript function:
function ConvertDate(dtin){
var d = new Date(dtin);
var convertdate = d.getUTCFullYear() + '-' + ('0' + (d.getUTCMonth()+1)).slice(-2) + '-' + ('0' + d.getUTCDate()).slice(-2) +'T' + ('0' + d.getUTCHours()).slice(-2)+':'+('0' + d.getUTCMinutes()).slice(-2)+':'+d.getUTCSeconds()+'0';
return convertdate;
}
From there I could pass the converted date to the sObject function without error.

Need help converting vbs code to jscript. Im getting a Runtime Error Type Mismatch

Ive got this labratory equipment that is connected to my PC. It uses special OCX file to communicate with the device (reading, setting parameters and such). I got this code from manual that seems to be working. I get a message box saying "Magnification =1272.814 Last error=API not initialized".
<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
Dim Value
Dim er
call Api1.Initialise("")
call Api1.Get("AP_MAG",Value)
call Api1.GetLastError(er)
call window.alert("Magnification = " + CStr(Value)+"Last error="+er)
call Api1.ClosingControl()
end sub
-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<object classid="CLSID:71BD42C4-EBD3-11D0-AB3A-444553540000" id="Api1">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2096">
<PARAM NAME="_ExtentY" VALUE="1058">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>
So because I have 0% knowledge in vbs and about 10% in jscript I`m trying to rewrite the same thing in Javascript. And I also have some necessary code already written in js.
<script language="JScript">
var Api1=new ActiveXObject("ApiCtrl");
var value;
var er;
Api1.Initialise("");
Api1.Get("AP_MAG",value);
Api1.GetLastError(er);
window.alert("Magnification = " + value+"\n Last error="+er);
Api1.ClosingControl();
</script>
Unfortunately I get a type mismatch error in either .Get or .GetLastError methods either with var value; var er; or var value=""; var er="";
Here is what API manual has to say
long GetLastError(VARIANT* Error)
[out] Error is the error string
associated with the error code for the last error
Remarks: This call will return a VT_BSTR VARIANT associated with the last error. Return
Value: If the call succeeds, it returns 0. If the call fails, an error
code is returned from the function.
long Get(LPCTSTR lpszParam, VARIANT* vValue)
[in] lpszParam is the name of the parameter e.g. “AP_MAG”
[in][out] vValue is the value of the parameter Remarks: This call will get the
value of the parameter specified and return it in vValue. In C++,
before calling this functions you have to specify the variant type
(vValue.vt) to either VT_R4 or VT_BSTR. If no variant type is defined
for vValue, it defaults to VT_R4 for analogue parameters (AP_XXXX) and
VT_BSTR for digital parameters (DP_XXXX). If the variant type is VT_R4
for an analogue parameter, then the floating point representation is
returned in the variant. If a VT_BSTR variant is passed, analogue
values are returned as scaled strings with the units appended (e.g.
AP_WD would return “= 10mm”). For digital parameters, VT_R4 variants
result in a state number and VT_BSTR variants result in a state string
(e.g. DP_RUNUPSTATE would return state 0 or “Shutdown” or the
equivalent in the language being supported). In C++, if the variant
type was specified as VT_BSTR then the API will internally allocate a
BSTR which the caller has to de-allocate using the SDK call
::SysFreeString (vValue.bstrVal)
Welcome to StackOverflow!
Well, each language is made with purpose. Then come to deal with ActiveX objects in browser (or WSH) environment, VBScript is the best choice, while JavaScript is most worst.
JavaScript hasn't so-called out parameters. That mean all function arguments are passed by value (as copy). Lets show you this with examples.
' VBScript
Dim X, Y
X = 1
Y = 2
Foo X, Y
MsgBox "Outer X = " & X & ", Y = " & Y
'> Local args: 6, 8
'> Outer X = 1, Y = 8
Sub Foo(ByVal arg1, ByRef arg2)
arg1 = 6
arg2 = 8
MsgBox "Local args: " & arg1 & ", " & arg2
End Sub
By default in VBS the arguments are passed by reference, so ByRef prefix in function arguments declaration is optional. I include it for clarity.
What the example illustrate is the meaning of "by reference" or "out" parameter. It behave like return value because it modify referenced variable. While modifying "by value" variable has no effect outside of the function scope, because we modify a "copy" of that variable.
// JavaScript
function foo(arg1) {
arg1 = 2;
alert('Local var = ' + arg1);
}
var x = 0;
foo(x);
alert('Outer var = ' + x);
// Local var = 2
// Outer var = 0
Now take a look at this thread. Looks like there is a kind of partial solution by using empty objects. I'm not sure in which cases that will work, but for sure it's very limited hack.
If this not help in your case, then looks like it's time to go with VBScript. Starting with VBS is easy anyway. It's the most user friendly language I ever touch. I was need days, even weeks with other languages only to get started, while just after a few hours with VBS I was able to use it freely.
[EDIT] Well, I made a lot more efforts to reply as may looks like at the glance :) Starting with the language limitation you met. Afterwards going to explain the nature of that limitation (what's "in/out" parameter), and the best way to do that is via example, and this is what I did. Afterwards I show you the only workaround out there to deal with this limitation in JS. Can we consider this as complete answer?
You not mention whether you test this "empty-object-trick", but as you still asking I presume you did that and it's not work with your OCX, right? Then, in this case, you're just forced to deal with your OCX via VBScript, what was my answer from the beginning. And as you prefer to stay with JS then you need to integrate a piece of VB code in your solution.
And as you noted too, this VBs/Js integration is a whole new question. Yes, good question of course, but it's a metter of new topic.
Ok, lets say that the question you append below: "why it should work with passing objects as a function parameter", is still a part of the main question. Well, as you see, even people using JS daily (am not one of them) has no idea what happens "behind the hood", i.e. do not expect an answer on what the JS-engine do in this case, or how this cheat the JS-engine to do something that it's not designed to do. Personally, as I use JS very rarely and not for such tasks, am not even sure if this trick works at all. But as the JS-guys assert it works (in some cases) then we s'd trust them. But that's all about. If this approach fail then it's not an option.
Now what's remain is a bit of homework, you s'd research all available methods for VBs/Js integration, also test them to see which one is most applicable to your domain, and if by chance you meet with difficulties, just then come-back to the forum with new topic and the concrete issue you're trying to resolve.
And to become as helpful as possible, I'll facilitate you with several references to get started.
Here is the plan...
1. If it's possible to work without VBs/Js integration then use stay-alone .VBS files (in WSH environment), else ...
2. In case you work in browser environment (HTML or HTA) then you can embed both (VBs/Js), and your integration w'd be simple.
3. Or may integrate VBs/Js with Windows Script Files (.wsf).
4. Or use ScriptControl that allow running VBScript from within JScript (or backward/opposite).
Links:
Using the ScriptControl
How To Call Functions Using the Script Control
An example VBs/Js integration using ScriptControl via
Batch-Embeded-Script
What is Batch-Embeded-Script:
VBS/Batch Hybrid
JS/Batch Hybrid
5. Some other method (if you find, that am not aware of).
Well, after all this improvements I not see what I can append more, and as I think, now
my answer is more than complete. If you agree with my answer then accept it by clicking on the big white arrow. Of course, if you expect to get better reply from other users, you may still wait, but keep in mind that unanswered questions stay active just for awhile and then become closed.

Categories