Unit test directive inside a directive - unit-testing

I'm having troubles unit testing a directive that wraps the ng-grid component.
I've written this punkler that shows the issue : http://plnkr.co/edit/HlB8Bt9M2TzsyM6XaDso?p=preview
There is a lot of code I know, but I can't reduce it more than that.
Basically, there is a custom-grid directive that wrapps the ng-grid component from angular-ui. I've made this directive because I have lots of grids in my app and I wouldn't duplicate the configuration of the grid.
The grid displayed on top of the test results use this directive. So , you can see it works fine :)
However, there is probably something I miss about how to test this directive.
I've written a simple test that assert that the first row, first col displays 'Martoni' but it fails. The same test using the ng-grid directive pass.
Any idea what's wrong in my test code ?

http://plnkr.co/edit/WwTyuQXNklL7CnjOxsB2?p=preview
I've had issues before calling directives recursively (or at least nested-ly), particularly when they make use of the $compile service (and ng-repeat's, especially). I'm convinced there's a bug there but I haven't taken the time to find an isolated case. Anyway I think what you've found is some sort of bug, but there's an easy workaround.
If you look at the source for ngGrid you'll see that columns are only added if the width is big enough. When I stepped through in your second example w was negative, which led to addCol never being called.
var w = col.width + colwidths;
if (col.pinned) {
addCol(col);
var newLeft = i > 0 ? (scrollLeft + totalLeft) : scrollLeft;
domUtilityService.setColLeft(col, newLeft, self);
totalLeft += col.width;
} else {
if (w >= scrollLeft) {
if (colwidths <= scrollLeft + self.rootDim.outerWidth) {
addCol(col);
}
}
}
colwidths += col.width;
This led me to believe that your elements had 0 height/width, which could be because they weren't actually in the document while they were being unit-tested.
So to fix it I added the following before your compile(elm)($scope);
angular.element('body').append(elm);
And then to clean up:
afterEach(function () {
angular.element(elm).remove();
});
I don't know if it was intentional or not, but you called $new() on $rootScope in the first unit test but didn't use the result of that to compile with, whereas you did it in the second.

Related

Is there a way to specify an NUnit test as "extra credit"?

I have a few tests for an API, and I would like to be able to express certain tests that reflect "aspirational" or "extra credit" requirements - in other words, it's great if they pass, but fine if they don't. For instance:
[Test]
public void RequiredTest()
{
// our client is using positive numbers in DoThing();
int result = DoThing(1);
Assert.That( /* result is correct */ );
}
[Test]
public void OptionalTest()
{
// we do want to handle negative numbers, but our client is not yet using them
int result = DoThing(-1);
Assert.That( /* result is correct */ );
}
I know about the Ignore attribute, but I would like to be able to mark OptionalTest in such a way that it still runs on the CI server, but is fine if it does not pass - as soon as it does, I would like to take notice and perhaps make it a requirement. Is there any major unit test framework that supports this?
I would use a Warnings to achieve this. That way - your test will print a 'warning' output, but not be a failure, and not fail your CI build.
See: https://github.com/nunit/docs/wiki/Warnings
as soon as it does, I would like to take notice and perhaps make it a requirement.
This part's a slightly separate requirement! Depends a lot on how you want to 'take notice'! Consider looking at Custom Attributes - it may be possible to write an IWrapSetUpTearDown attribute, which sends an email when the relevant test passes. See the docs, here: https://github.com/nunit/docs/wiki/ICommandWrapper-Interface
The latter is a more unusual requirement - I would expect to have to do something custom to fit your needs there!

SLOC in cppcheck

I want to write checker that can be added to other checkers in CppCheck. This checker must check SLOC of all member function, for example the function should contain no more than 200 significant lines of code. But in CppCheck I only found method that checks the existence of a body hasBody(), but not a count of lines.
I am a cppcheck developer. I am no expert in this topic. I think it depends on exactly what you want to count. how many lines is this:
void f() { int x=3; int y=x+2; dostuff(x+y+4); }
I would guess that you want to go through the tokens and count semicolons or something:
for (tok = functionScope->classStart; tok != functionScope->classEnd; tok = tok->next()) {
if (tok->str() == ";")
++lines;
}
I think this checker you suggest is interesting but it does not fit well in the core cppcheck tool. I would suggest that you write an addon. I will be happy to add it in our addons folder and show it in the GUI etc.
By the way.. I have thought that it would be nice to integrate (execute and read results) ohcount, cccc, or whatever in the GUI so extended statistics can be shown.

Better errors with Ember

Is there a way to have clearer error messages when something is wrong with ember?
For exemple, I have this error 05:10:32,332 Error: Assertion Failed: A helper named 'eq' could not be found1 vendor.self-4fd4ab06f1f66c1cec72e1ec3a2c99328df792e46fb1fdcd0258c341b30a7c3b.js:24472:0
. This error is not the subject of the question, this is just an example.
I have no idea where is eq. The console indicated this function :
function EmberError() {
var tmp = Error.apply(this, arguments);
// Adds a `stack` property to the given error object that will yield the
// stack trace at the time captureStackTrace was called.
// When collecting the stack trace all frames above the topmost call
// to this function, including that call, will be left out of the
// stack trace.
// This is useful because we can hide Ember implementation details
// that are not very helpful for the user.
if (Error.captureStackTrace) {
Error.captureStackTrace(this, _emberMetalCore.default.Error);
}
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
}
This is not related to my problem.
Obviouly, I searched eq in my code and I have no results. I suppose this is in a module but using grep is very ineffective.
Sometimes there is a stacktrace but its not very efficient too. To find an addon or the source in my code in a big vendor.js or myapp.js is not ideal.
Is there a better solution?
I think something in one of your addons or other third party code is using the ember-truth-helpers addon.
vendor.js typically contains third party code you've imported, not code that you've wrote.
As to the basic issue, it is really up to the maker of the third party code you've imported to document its dependencies and to ensure they are installed when you install that dependency. This really is not a failing of Ember itself, it has told you that there is no helper named eq and has given you the line number in the precompiled template where the eq was used. You can use the sources tab in Chrome to scroll to line 24472 in vendor.self-4fd4ab06f1f66c1cec72e1ec3a2c99328df792e46fb1fdcd0258c341b30a7c3b.js

XCTest fails with with exception 'Non-UI clients cannont be autopaused'

I am trying to test creation of CLLocationManager as a singletone with default parameters:
+ (GeolocationService *)defaultGeolocationService
{
static GeolocationService *_defaultGeolocationService = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_defaultGeolocationService = [[GeolocationService alloc] init];
[_defaultGeolocationService initLocationManager];
});
return _defaultGeolocationService;
}
- (void)initLocationManager
{
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = YES;
[self.locationManager requestAlwaysAuthorization];
}
Test looks like this:
- (void)testInitWithDefaultsSettings
{
GeolocationService *defaultGeolocationService = [GeolocationService defaultGeolocationService];
XCTAssertTrue(defaultGeolocationService.settings.autoPause, #"autoPause");
}
And I get an exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Non-UI clients cannont be auto paused'
What should I do to make this test work?
The issue is with the following line
self.locationManager.pausesLocationUpdatesAutomatically = YES;
This property cannot be set on an application that is not running a UI (not sure why, I could not find any documentation about it).
You may want to do some checks in your test to ensure that the UI has loaded before initialising your GeoLocationService and setting self.locationManager.pausesLocationUpdatesAutomatically.
I searched a bit on simple and fast solution to avoid it and I have found some workaround to this problem I think you have three solutions :
- Easy One :
Create a Preprocessor Macro for Testing Target. But it's depend on how many Macro you have and can complicate the code management if you abuse on it.
- Medium one :
You know that all unit test are running on a simulator so why not try a
#if !(TARGET_IPHONE_SIMULATOR)
But you will tell me that you want as well to run the app on your simulator and if you do only that case you won't be able to use the property on the app launching case in the simulator.
So why not add a complementary test about knowing what XPCServiceName is running like below :
NSString *serviceName = [NSProcessInfo processInfo].environment[#"XPC_SERVICE_NAME"];
BOOL amITesting = ([serviceName rangeOfString:#"xctest"].location != NSNotFound);
So with #if !(TARGET_IPHONE_SIMULATOR) && !amITesting you can use your
self.locationManager.pausesLocationUpdatesAutomatically = YES;
And Test will pass.
- Third one :
I don't like this solution but I write it as well, it's the monkey solution... If you don't want to add a Pre-Processor Macro, add a try catch and test will pass as well. But I don't advice you to use that one.
I hope it will helps a bit more.
This is a restriction of unit tests and other non-UI processes, reason only known to Apple. Here is a solution I am using:
let serviceName = ProcessInfo.processInfo.environment["XPC_SERVICE_NAME"]
let testing = serviceName?.hasSuffix("xctest") ?? false
if !testing {
locationManager.pausesLocationUpdatesAutomatically = true
}

How to test asynchronuous code

I've written my own access layer to a game engine. There is a GameLoop which gets called every frame which lets me process my own code. I'm able to do specific things and to check if these things happened. In a very basic way it could look like this:
void cycle()
{
//set a specific value
Engine::setText("Hello World");
//read the value
std::string text = Engine::getText();
}
I want to test if my Engine-layer is working by writing automated tests. I have some experience in using the Boost Unittest Framework for simple comparison tests like this.
The problem is, that some things I want the engine to do are just processed after the call to cycle(). So calling Engine::getText() directly after Engine::setText(...) would return an empty string. If I would wait until the next call of cycle() the right value would be returned.
I now am wondering how I should write my tests if it is not possible to process them in the same cycle. Are there any best practices? Is it possible to use the "traditional testing" approach given by Boost Unittest Framework in such an environment? Are there perhaps other frameworks aimed at such a specialised case?
I'm using C++ for everything here, but I could imagine that there are answers unrelated to the programming language.
UPDATE:
It is not possible to access the Engine outside of cycle()
In your example above, std::string text = Engine::getText(); is the code you want to remember from one cycle but execute in the next. You can save it for later execution. For example - using C++11 you could use a lambda to wrap the test into a simple function specified inline.
There are two options with you:
If the library that you have can be used synchronously or using c++11 futures like facility (which can indicate the readyness of the result) then in your test case you can do something as below
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (!Engine::isResultReady());
//read the value
assert(Engine::getText() == "WHATEVERVALUEYOUEXPECT");
}
If you dont have the above the best you can do have a timeout (this is not a good option though because you may have spurious failures):
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (Engine::getText() != "WHATEVERVALUEYOUEXPECT") {
wait(1 millisec);
if (total_wait_time > 1 sec) // you can put whatever max time
assert(0);
}
}