Let say I have this code:
void test(){
assert(() {
print("This is Test");
});
}
As per this question, dart will remove assert on production build
but how about test() function which being called?
will this function be removed on build?
or will this have any significant impact on performance if I call empty function multiple times?
The compiler will optimize your code through inlining and removing calls to empty functions.
will this function be removed on build?
Not unless you use it only within other asserts. A typical example would be this:
assert(() {
test();
return true;
}());
If you only use it this way, then yes the function will be removed on build.
Related
I need to check for fullscreen support with my Go WASM Canvas project, before switching to fullscreen mode. I have the following code so far:
var fullscreenFunc js.Value
var fullscreenNotSupported bool
set with the following logic:
fullscreenFunc = app.Get("requestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("mozRequestFullScreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("webkitRequestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("msRequestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenNotSupported = true
println("Fullscreen not supported")
}
}
}
}
I was expecting to be able to call the correct function with js.Invoke, but I see no way to tell the Invoke upon which object the call should be made. My 'app' value is being interpreted just as a param.
func Fullscreen(app js.Value) {
if fullscreenNotSupported {
return
}
fullscreenFunc.Invoke(app)
}
resulting in:
panic: JavaScript error: 'mozRequestFullScreen' called on an object that does not implement interface Element.
So am I correct in my thinking that the only way I can call the correct method, is not to store the Function, but to store a string of the function name, and then 'invoke' / 'call' it using the following approach?
app.Call(fullscreenFunctionNameString)
It feels like I misunderstood the purpose of Invoke. Is it only for js.Global() type calls?
[edit] Using 'Call', at least it seems possible to derive the function name without having to repeat the above browser specifics:
fullscreenFunctionName = fullscreenFunc.Get("name").String()
app.Call(fullscreenFunctionNameString)
It doesn't answer the question, but is probably of help to someone trying to do the same.
The arguments to invoke get turned into arguments for the javascript function it wraps. Since those fullscreen functions don't need any arguments, I think you might just need to change:
fullscreenFunc.Invoke(app)
To:
fullscreenFunc.Invoke()
...assuming app is the same JS element in both places. If not your Call solution is probably your best bet.
I am fairly new to Test Driven Development and I just started learning the SOLID principles so I was hoping someone could help me out. I'm having some conceptual trouble understanding the Single Responsibility Principle in the context of developing unit tests and methods in the TDD paradigm. For instance, say I want to develop a method that deletes an item from a database- before my code would have looked like the following...
I'd start with defining a test case:
"Delete_Item_ReturnsTrue": function() {
//Setup
var ItemToDelete = "NameOfSomeItem";
//Action
var BooleanResult = Delete( ItemToDelete );
//Assert
if ( BooleanResult === true ) {
return true;
} else {
console.log("Test: Delete_Item_ReturnsTrue() - Failed.");
return false;
}
}
I'd run the test to make sure it failed, then I'd develop the method...
function Delete( ItemToDelete ) {
var Database = ConnectToDatabase();
var Query = BuildQuery( ItemToDelete );
var QueryResult = Database.Query( Query );
if ( QueryResult.error !== true ) {
//if there's no error then...
return true;
} else {
return false;
}
}
If I'm understanding the Single Responsibility Principle correctly, the method that I originally wrote had the responsibilities of deleting the item AND returning true if there wasn't an error. So if I follow the SOLID paradigm the original method should be refactored to look something like...
function Delete( WhatToDelete, WhereToDeleteItFrom ) {
WhereToDeleteItFrom.delete( WhatToDelete );
}
Doing the design as such, changed my method from a boolean function to a void function so now I can't really test the new method in the same manner I was testing my old method.
I guess I could test for thrown exceptions but then doesn't that make it an integration test rather than a unit test because there's no actual exception thrown in the method?
Do I design and implement an extra function which checks the database for use in my unit test?
Do I just not test it because it's void? How exactly does that work in TDD?
Do I pass in a mock repository and then return it after it's state has changed? Doesn't that just essientially bring me back to square one?
Do I pass in a reference to a mock repository and then just test against the repository after the method completes? Wouldn't that be considered a side effect though?
So the single responsibility principle says: They should be exact one reason when I need to change a function.
So let's look at your function:
function Delete( ItemToDelete ) {
var Database = ConnectToDatabase();
var Query = BuildQuery( ItemToDelete );
var QueryResult = Database.Query( Query );
if ( QueryResult.error !== true ) {
//if there's no error then...
return true;
} else {
return false;
}
}
Database changes: ConnectToDatabese() needs a change, but not this function
Changes in the db structure: BuildQuery() needs to be changed (maybe)
...
So on the first look, your function looks good. The naming on some places is a little bit confusing. A function should be start with a small letter. For example "connectToDatabase()". It is a little bit surprising that connectToDatabase returns an Object.
The name BuildQuery seems to be wrong, because BuildQuery( myItem ) returns a query wich is deleting something.
But I would never have such a long complicated function which just one testcase.
You need to write more test cases.
For the first test case you could write the function like that:
function Delete( ItemToDelete) {
return true
}
The next testcase could be "call the buildDeleteQuery function with the item id". At that point you need to think about how you call your db. If you have a dbObject, which does that you could mock that Object.
function Delete( ItemToDelete ) {
buildDeleteQuery( ItemToDelete.id )
return true
}
Now more and more test cases. Remember that there will be also test cases for buildDeleteQuery. But for the outer function you could mock buildDeleteQuery.
Now to answer some of your questions:
When you first write the test and then write the code, you will have testable code.
That code looks different, because the tests should be not to complicated. When you want easy tests you will automaticly have more smaller functions.
Yes, you will write a test for every function you call.
Maybe you will mock objects. And if you are not able to test your db call without a wrapping function you will create a function, which allows you to test that functionality.
Remember your tests are the documentation of your code. So keep them simple as possible.
But the most important thing: Keep practicing! When you start with TDD it takes some time. A good and fun resource is: Uncle Bobs Bowling Kata Just download the slides from the website and look how tdd is done step by step.
I have some tests that fail in PhantomJS but not other browsers.
I'd like these tests to be ignored when run with PhantomJS in my watch task (so new browser windows don't take focus and perf is a bit faster), but in my standard test task and my CI pipeline, I want all the tests to run in Chrome, Firefox, etc...
I've considered a file-naming convention like foo.spec.dont-use-phantom.js and excluding those in my Karma config, but this means that I will have to separate out the individual tests that are failing into their own files, separating them from their logical describe blocks and having more files with weird naming conventions would generally suck.
In short:
Is there a way I can extend Jasmine and/or Karma and somehow annotate individual tests to only run with certain configurations?
Jasmine supports a pending() function.
If you call pending() anywhere in the spec body, no matter the expectations, the spec will be marked pending.
You can call pending() directly in test, or in some other function called from test.
function skipIfCondition() {
pending();
}
function someSkipCheck() {
return true;
}
describe("test", function() {
it("call pending directly by condition", function() {
if (someSkipCheck()) {
pending();
}
expect(1).toBe(2);
});
it("call conditionally skip function", function() {
skipIfCondition();
expect(1).toBe(3);
});
it("is executed", function() {
expect(1).toBe(1);
});
});
working example here: http://plnkr.co/edit/JZtAKALK9wi5PdIkbw8r?p=preview
I think it is purest solution. In test results you can see count of finished and skipped tests.
The most simple solution that I see is to override global functions describe and it to make them accept third optional argument, which has to be a boolean or a function returning a boolean - to tell whether or not current suite/spec should be executed. When overriding we should check if this third optional arguments resolves to true, and if it does, then we call xdescribe/xit (or ddescribe/iit depending on Jasmine version), which are Jasmine's methods to skip suite/spec, istead of original describe/it. This block has to be executed before the tests, but after Jasmine is included to the page. In Karma just move this code to a file and include it before test files in karma.conf.js. Here is the code:
(function (global) {
// save references to original methods
var _super = {
describe: global.describe,
it: global.it
};
// override, take third optional "disable"
global.describe = function (name, fn, disable) {
var disabled = disable;
if (typeof disable === 'function') {
disabled = disable();
}
// if should be disabled - call "xdescribe" (or "ddescribe")
if (disable) {
return global.xdescribe.apply(this, arguments);
}
// otherwise call original "describe"
return _super.describe.apply(this, arguments);
};
// override, take third optional "disable"
global.it = function (name, fn, disable) {
var disabled = disable;
if (typeof disable === 'function') {
disabled = disable();
}
// if should be disabled - call "xit" (or "iit")
if (disable) {
return global.xit.apply(this, arguments);
}
// otherwise call original "it"
return _super.it.apply(this, arguments);
};
}(window));
And usage example:
describe('foo', function () {
it('should foo 1 ', function () {
expect(true).toBe(true);
});
it('should foo 2', function () {
expect(true).toBe(true);
});
}, true); // disable suite
describe('bar', function () {
it('should bar 1 ', function () {
expect(true).toBe(true);
});
it('should bar 2', function () {
expect(true).toBe(true);
}, function () {
return true; // disable spec
});
});
See a working example here
I've also stumbled upon this issue where the idea was to add a chain method .when() for describe and it, which will do pretty much the same I've described above. It may look nicer but is a bit harder to implement.
describe('foo', function () {
it('bar', function () {
// ...
}).when(anything);
}).when(something);
If you are really interested in this second approach, I'll be happy to play with it a little bit more and try to implement chain .when().
Update:
Jasmine uses third argument as a timeout option (see docs), so my code sample is replacing this feature, which is not ok. I like #milanlempera and #MarcoCI answers better, mine seems kinda hacky and not intuitive. I'll try to update my solution anyways soon not to break compatibilty with Jasmine default features.
I can share my experience with this.
In our environment we have several tests running with different browsers and different technologies.
In order to run always the same suites on all the platforms and browsers we have a helper file loaded in karma (helper.js) with some feature detection functions loaded globally.
I.e.
function isFullScreenSupported(){
// run some feature detection code here
}
You can use also Modernizr for this as well.
In our tests then we wrap things in if/else blocks like the following:
it('should work with fullscreen', function(){
if(isFullScreenSupported()){
// run the test
}
// don't do anything otherwise
});
or for an async test
it('should work with fullscreen', function(done){
if(isFullScreenSupported()){
// run the test
...
done();
} else {
done();
}
});
While it's a bit verbose it will save you time for the kind of scenario you're facing.
In some cases you can use user agent sniffing to detect a particular browser type or version - I know it is bad practice but sometimes there's effectively no other way.
Try this. I am using this solution in my projects.
it('should do something', function () {
if (!/PhantomJS/.test(window.navigator.userAgent)) {
expect(true).to.be.true;
}
});
This will not run this particular test in PhantomJS, but will run it in other browsers.
Just rename the tests that you want to disable from it(...) to xit(...)
function xit: A temporarily disabled it. The spec will report as
pending and will not be executed.
I'm writing an HTML5 / JavaScript app for multiple devices, but my issue comes when writing it for Win8 and iOS.
Due to Win8's strict security, I need to wrap certain functions, specifically those that inject HTML or divs into the window, in a WinJS function called execUnsafeLocalFunction.
When I go to run this same app on iOS, it cannot run those functions because WinJS does not exist.
How can I create a conditional statement so that it checks if the device running the app is a Win8 device, or iOS? This way I can tell it to run function foo or function bar.
JavaScript doesn't presently support conditional compilation, so I think you need to write your own stub functions that wrap those like execUnsafeLocalFunction. In that function you'd test whether the function exists by checking the namespaces. Something like:
function callUnsafeFunction(func) {
if (MSApp && MSApp.execUnsafeLocalFunction) {
return MSApp.execUnsafeLocalFunction(func);
} else {
return func()
}
}
Alternately, you can check if the function exists in the namespace, and if not, add you own function of the same name as a passthrough, something like this (I haven't tested such code):
if (!(MSApp && MSApp.execUnsafeLocalFUnction)) {
window.MSApp = {
execUnsafeLocalFunction: function(func) {
func();
}
};
}
In short, the conditional check is the existence of a namespace/function, because we don't have conditional compilation.
Say I have a function
void do_something() {
//....
#ifdef FEATURE_X
feature_x();
#endif
//....
}
I can compile and run this with no problems; if I want the feature I can pass -D FEATURE_X and it works.
However, what if I would like to put do_something into another file (And not have to recompile that file as well each time I decide to change the option). If it was in the same file, I assume that
const int FEATURE_X=0;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
will use dead code elimination properly, eliminating the call. If I put this in another file, without LTO,
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
It will not remove the code (It has no way of knowing). So, with link time optimization enabled, can the compiler detect the value of FEATURE_X at link time, determine if the code is used or not, and remove it if appropriate?
GCC does cross module unreachable function removal, but it will not be able to determine the code is dead in your last testcase, because the constant value of FEATURE_X will be determined too late.
If you will use -D way or put your const int FEATURE_X=0; into every module then yes, the code will be eliminated.