Code Monkey home page Code Monkey logo

buddy's Introduction

Buddy

Your friendly BDD testing library for Haxe!

Quickstart

  1. Install the lib:

haxelib install buddy

  1. Create a test file called Main.hx:
using buddy.Should;

class Main extends buddy.SingleSuite {
    public function new() {
        // A test suite:
        describe("Using Buddy", {
            var experience = "?";
            var mood = "?";

            beforeEach({
                experience = "great";
            });

            it("should be a great testing experience", {
                experience.should.be("great");
            });

            it("should make the tester really happy", {
                mood.should.be("happy");
            });

            afterEach({
                mood = "happy";
            });
        });
    }
}
  1. Make a quick test:

haxe -x Main -lib buddy

..
Using Buddy
  should be a great testing experience (Passed)
  should make the tester really happy (Passed)
2 specs, 0 failures, 0 pending

But please don't stop there. Try using it on other targets than Neko, Buddy supports them all on both Windows and Linux, even Hashlink if you're using Haxe 4. The only thing you need to remember is to add -D nodejs to your hxml if you're targeting Node.js, but that is usually taken care of by libraries like hxnodejs.

Asynchronous support

Buddy was built from the ground up to have great support for async testing, so it's fully compatible with Node.js and handles ajax requests with ease. To use it, just create the specification with a function that takes one argument (targeting javascript now):

using buddy.Should;

class Main extends buddy.SingleSuite {
    public function new() {
        describe("Using Buddy asynchronously", {
            var mood = "?";

            // Add function(done) here to enable async testing:
            beforeAll(function(done) {
                haxe.Timer.delay(function() {
                    mood = "thrilled";
                    done(); // Call the done() function when the async operation is complete.
                }, 100);
            });

            // Can be added to "it" and "after" as well if needed.
            it("can be described in a certain word", {
                mood.should.be("thrilled");
            });
        });
    }
}

The default timeout is 5000 ms, after which the spec will automatically fail if done() hasn't been called. If you want to change the timeout, set the property timeoutMs in the BuddySuite before the actual it() specification, or in the before/after block. Here's an example:

using buddy.Should;

class Main extends buddy.SingleSuite {
    public function new() {
        describe("Using Buddy asynchronously", {
            timeoutMs = 100;
            it("should fail specs after a timeout set before it()", function(done) {
                // This test will fail after 100 ms.
                haxe.Timer.delay(done, 200);
            });
        });
    }
}

You can set timeoutMs to 0 to disable the timeout check. Note: When using function(done), on some targets the timeout check will run in a separate thread. Also, timeouts and asynchronous behavior aren't supported when targeting PHP or interp.

Before/After

To setup tests, you can use beforeAll, beforeEach, afterEach and afterAll:

using buddy.Should;

class BeforeAfterTest extends buddy.SingleSuite {
    public function new() {
        describe("Using before/after", {
            // vars will be set one time only, before any tests run.
            var test = 0;

            // Will run once as the first thing in the current describe block
            beforeAll({
                test++;
            });

            // Will run before each "it" in the current and before each "it" in any nested describes.
            beforeEach({
                test++;
            });

            it("should be a convenient way to set up tests", {
                test.should.be(2);
            });

            describe("When nesting describes", {
                beforeEach({
                    test++;
                });
                
                it("should run all before/afterEach defined here or above", {
                    test.should.be(3);
                });
                
                afterEach({
                    test--;
                });
            });
            
            it("should run in correct order too", {
                test.should.be(2);
            });

            // Will run after each "it" in the current and before each "it" in any nested describes.
            afterEach({
                test--;
            });

            // Will run once as the last thing in the current describe block
            afterAll({
                test--;
            });
        });
    }
}

"Should" assertions

As you've seen in the examples, testing if specifications are correct is as simple as adding using Buddy.should to the package and then use the should extension for the identifier you want to test. The following assertions are supported:

All types

a.should.be(b) - Tests equality for value types (Bool, Float, Int, Int64, and the immutable String) and identity for the other (reference) types.

a.should.beType(b) - Tests if a is of type b. Basically a wrapper around Std.is.

Int / Int64

a.should.beLessThan(b)

a.should.beLessThanOrEqualTo(b)

a.should.beGreaterThan(b)

a.should.beGreaterThanOrEqualTo(b)

Float

Same as Int plus

a.should.beCloseTo(b, p = 2) - a should be close to b with p decimals precision, so you can easily compare floats without worrying about precision issues.

String

a.should.contain(substr) - Test if a contains a given substring.

a.should.match(regexp) - Test if a matches a regular expression (EReg).

a.should.startWith(substr) - Test if a starts with a given substring.

a.should.endWith(substr) - Test if a ends with a given substring.

Date

a.should.beOn(date) - Test if a is on a given date

a.should.beOnStr(string) - Test if a is on a date specified by a string in the Date.fromString accepted formats.

a.should.beBefore(date) - Test if a is before a given date.

a.should.beBeforeStr(string) - Same as above, but specified by a string.

a.should.beAfter(date) - Test if a is after a given date.

a.should.beAfterStr(string) - Same as above, but specified by a string.

Iterable

a.should.contain(b) - Test if an Iterable contains b.

a.should.containAll(b) - Test if an Iterable contains all objects in Iterable b.

a.should.containExactly(b) - Test if an Iterable contains exactly the same objects as in Iterable b and in the same order.

Enum

a.should.equal(b) - Makes a deep equality check, using Type.enumEq. A warning will be given when enums are compared by should.be, since the result of that comparison is undefined.

Exceptions

Testing if a function throws an exception is made easy using the special bind field which exists for every function.

If the function signature is String -> Void then apply the string argument like this:

a.bind("test").should.throwValue("error")

a.bind("test").should.throwType(String)

a.bind("test").should.throwAnything()

You can also test an anonymous function directly:

(function() { throw "error"; }).should.throwType(String)

The throw methods will return the exception object, so it can be tested further. This works synchonously only.

Inverting assertions

Every assertion can be negated using not which is present on all should fields:

a.should.not.contain("test")

Failing tests

A test can be failed using the fail(o : Dynamic) : Void method available in a BuddySuite. The test will fail with the string value of o as a message. If you're testing asynchronously you can pass the fail method to the error handler. Here are some examples:

it("should fail manually when using fail()", {
    fail("Totally on purpose.");
});

it("should fail if a promise fails", function(done) {
    request.getJson("/some/url")
    .then(function(r) {
        r.statusCode.should.be(200);
        done();
    })
    .catchError(fail);
});

it("should also fail when throwing an exception", {
    throw "But only synchronously!";
});

Testing compilation failures

If you want to test if some part of your code fails to compile, guess what, there is a macro for that:

import buddy.CompilationShould;

class Main extends buddy.SingleSuite
{
    public function new() {
        describe("Using CompilationShould", {
            it("should pass if an expression won't compile", {
                CompilationShould.failFor(this.will.not.compile);
            });
        });
    }
}

The method will return a string representation of the compilation failure, or an empty string if compilation succeded, in case you want to test it further.

General error handling

Exceptions in it will be handled as above, but if something goes wrong in a before/after section, Buddy will stop executing the whole suite. It will also count as a failure.

If you're getting an early runtime error, you might want to disable the trace capture that buddy uses. You can do that globally by putting BuddySuite.useDefaultTrace = true in the beginning of a test class. Then you'll see the traces immediately instead of in the reporter.

Please note that putting code that should be tested outside a describe, it or any before/after block can result in undefined behavior.

Pending tests

Since BDD is also made for non-programmers to use, a common development style is to write empty, or pending tests, and let a programmer implement them later. To do this, just write a string in the it methods, nothing else. Our previous test class would then look like this:

Main.hx

using buddy.Should;

class Main extends buddy.SingleSuite
{
    public function new() {
        describe("Using Buddy", {
            it("should be a great testing experience");
            it("should really make the tester happy");
        });
    }
}

And the output would be:

PP
Using Buddy
  should be a great testing experience (Pending)
  should really make the tester happy (Pending)
2 specs, 0 failures, 2 pending

There is also a pending(reason : String) method available to make a spec pending, similar to fail.

Including and excluding tests

Classes, suites and specs can all be marked with @include and @exclude metadata.

  • @include will only run the tests that are marked, removing everything else.
  • @exclude does the opposite, it removes the marked ones.

If you have a huge test suite, it can be convenient to mark the suite you're currently working on with @include.

Multiple test suites

Extending buddy.SingleSuite is nice and simple, but you can have multiple test classes, and separate them from the main class if you like. Here's how to do it:

Main.hx

import buddy.*;
using buddy.Should;

// Implement "Buddy" and define an array of classes within the brackets:
class Main implements Buddy<[
    Tests,
    path.to.YourBuddySuite,
    AnotherTestSuite,
    new SpecialSuite("Constant value", 123)
]> {}

// All test classes should now extend BuddySuite (not SingleSuite)
class Tests extends BuddySuite
{
    public function new() {
        describe("Using Buddy", {
            it("should be a great testing experience");
            it("should really make the tester happy");
        });
    }
}

Customizing output and reporting

Adding colors

Enable ANSI color output is easy:

@colorize
class Main extends buddy.SingleSuite {
    // ...
}

Or you can do it when compiling with -D buddy-colors, or disallow it with -D buddy-no-colors.

The compilation flag will override the metadata, if both are set.

Displaying only failing and pending tests

If you have lots of tests, failures may drown in the output. By defining -D buddy-ignore-passing-specs, only failed and pending test suites will be displayed in the final output.

Creating a custom reporter

You can make your own reporter by implementing the buddy.reporting.Reporter interface. Then there are two ways to use it:

@reporter("path.to.your.Reporter")
class Main extends buddy.SingleSuite {
    // ...
}

Or do it when compiling with -D reporter=path.to.your.Reporter.

The compilation flag will override the metadata, if both are set.

List of built-in Reporters

buddy.reporting.ConsoleReporter is the default reporter.

buddy.reporting.ConsoleFileReporter splits the test progress meter per file, in case you have many test suites in different files.

buddy.reporting.TraceReporter outputs to trace(), and is especially useful for CI with flash. If you define -D flash-exit, the default reporter will be the TraceReporter, and flash will exit if the correct permissions are set. This is tricky to get right, so the easiest way is to use travix.

buddy.reporting.XUnit2Reporting a reporter for xUnit.net.

FAQ

Where's main()?

Ok, you noticed that it was missing! Using some macro magic, you only need to extend buddy.SingleSuite, or alternatively implement buddy.Buddy on your Main class. Then platform-specific code will be generated for waiting until the tests are finished. On all server platforms, exit code 0 will be returned for "all tests passed" and 1 if not, so you can use Buddy in CI tools.

Autocompletion sometimes doesn't work for "x.should." or numbers.

The compiler seems to be a bit too good at optimizing sometimes, especially at the beginning of functions, though this seems to have improved greatly in 3.2. If you have this problem, add a parenthesis after "should", and wrap numbers in parenthesis too.

x.should.be("ok") -> x.should().be("ok")

123.should.beGreaterThan(100) -> (123).should.beGreaterThan(100)

Can I use other assertion libraries than the built-in 'should'?

Yes, there is special support for utest and general support for all libraries that throws an exception on failure (like mockatoo ). To use utest, just call any utest.Assert method inside a spec, no need to set up anything else.

There's an exception thrown in an asynchronous method, but Buddy won't catch it and fail the test?

It's not possible to do that, since the program has already passed the exception handling code when the exception is thrown. You need to handle asynchronous exceptions yourself and test if something went wrong before calling done in the spec, or use the fail method as described in the section "Failing tests".

I'm having problem compiling with C++

This usually happens if you're not linking in the correct .ndll files. An easy fix is to add -lib hxcpp to your hxml. Another problem could be fixed by adding -D HXCPP_M64 if you're targeting C++ on a 64bit platform (seems to vary between Linux and Win).

Can I run the tests manually, without generating main?

Yes, but make sure you know what you're doing, for example some targets requires a wait loop if you have asynchronous tests... Here's a minimal setup for synchronous execution:

import buddy.reporting.ConsoleColorReporter;

class Main {
    public static function main() {
        var reporter = new ConsoleColorReporter();

        var runner = new buddy.SuitesRunner([
            new FirstTestSuite(),
            new AnotherTestSuite()
        ], reporter);

        runner.run();
        
        #if sys
        Sys.exit(runner.statusCode());
        #end
    }
}

Please make sure that the auto-generated version doesn't work in your case, before doing this.

The story behind Buddy

After my speech about HaxeContracts at WWX2014, I concluded that one does not simply bash unit testing without providing a nice alternative! Having used Jasmine before, I borrowed some if its nice features, and found the perfect aid to implementing async support with the promhx library.

The HaxeContracts library is a nice complement to BDD, so check it out for more information about why most unit testing is waste, and why BDD is a better alternative...!

Upcoming features

  • Nicer browser reporter
  • Your choice! Send me a gmail (ciscoheat) or create an issue here.

Have a good time and much productivity with your new Buddy! :)

Build Status

buddy's People

Contributors

aidan63 avatar andyli avatar ciscoheat avatar dpomier avatar hamaluik avatar jasononeil avatar jcward avatar joel-arthur avatar kevinresol avatar klabz avatar mfoda avatar takashiski avatar terurou avatar waneck avatar yanhick avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

buddy's Issues

Working with HaxeFlixel projects

I tried taking the default HaxeFlixel template and integrating buddy tests with it, but I need some help. I added the Main.hx from the buddy readme to my project's root, and it runs fine from the command line. I then added this test to it (at the beginning of the constructor):

describe("A 100x100 rectangle at the origin", {
    var rect = new FlxRect( 0, 0, 100, 100 );
    it("should contain the point 50, 50", {
        rect.containsPoint( new FlxPoint( 50, 50 ) );
    });
});

I made sure the correct libraries were imported for FlxRect and FlxPoint, and added -lib flixel to the command for running the tests. I then get this error:

...\buddyhftest>haxe -lib buddy -lib flixel -main Main --interp
C:\HaxeToolkit\haxe\lib\flixel/git/flixel/math/FlxPoint.hx:3: characters 7-23 :
You cannot access the flash package while targeting neko (for flash.geom.Point)
Main.hx:2: characters 7-27 :     referenced here

Does this limitation mean that buddy isn't currently usable with a HaxeFlixel project?

beforeAll() and afterAll() feature

It would be great if we could use before() and after() only once before and after a test suite.

beforeAll/afterAll or some other method name would work exactly like actual before() and after() but just once.

Thanks for considering.

add it.only support

It's pretty useful once you started having lots of tests to only run a single one.
Could be used like so:

it.only('should run this test');

Thanks

befores do not stack.

A common pattern when working with nested describes is to do common configuration once in a before on the outer describe.

In buddy, though, the befores only seem to apply to the it calls directly within the describe.

It'd be nice if there was a stack of befores that would execute in the order of outermost first.

StackOverflow Exception due to large callstack in C#

I am running buddy using 10+ test "Suites". Each suite has over 20+ "Describes" containing 10+ "Its".

After the 30-35th testcase runs (30-35th dot is output) I get a StackOverflow Exception when targeting C#.

I added a printout for the callstack using CallStack.callStack().length in SuitesRunner.hx -> forEachSeries-> inside the next() function. It reaches well over 3,500 when the crash occurs. It looks like there are too many nested method calls in SuitesRunner.hx when you are running a lot of testcases in one batch.

Also, version 2.0.1 seemed stable for Java and Python, but 2.0.2 is causing failures for me in both languages.

Please let me know if you need any additional information.

Compilation error if haxelib dev buddy ...

I'm trying to hack buddy, so I manually cloned it and haxelib dev buddy path/to/buddy.
Try it with the following:

import buddy.*;
using buddy.Should;

class Test extends BuddySuite implements Buddy {
    public function new():Void {

    }
}

compilation error:

/Users/andy/Documents/workspace/buddy/src/buddy/tests/AllTests.hx:383: characters 4-17 : Unknown identifier : Assert
/Users/andy/Documents/workspace/buddy/src/buddy/tests/AllTests.hx:384: characters 4-15 : Unknown identifier : Assert
/Users/andy/Documents/workspace/buddy/src/buddy/tests/AllTests.hx:389: characters 4-17 : Unknown identifier : Assert
/Users/andy/Documents/workspace/buddy/src/buddy/tests/AllTests.hx:395: characters 5-17 : Unknown identifier : Assert

The interesting thing is if I disable the dev version, and use version 0.11.1 instead, it compiles fine.
Any idea?

err.should.be(null)

Not sure if this can be solved with macro but it would be great to be able to use should (even if value is null at runtime)

for example the following always fails

err.should.be(null)

if err is null you get

GenerateMain.hx:182: TypeError: Cannot read property 'should' of null

else you get an test error as err is not null

Issues running example

Hi,
I've installed buddy from haxelib, written the README example and ran it with:

  haxe -lib buddy -main Main --interp  

I get the following error:

/usr/lib/haxe/lib/buddy/0,1,0/buddy/Buddy.hx:3: characters 2-11 : Invalid package : lib.utest.compat.unit should be unit

I don't know where this is coming from, the only haxelib using utest I have installed seems to be promhx.

Thanks !

Std.toString() can execute function

This is not really a buddy issue but since a library I use in js have its property accessor made to execute function, some of my test are failing when there result are printed on screen. Would there be a way to disable Std.toString in the output?

Split the progress per file

Currently the progress bar looks like this:

.....PPPPXX.....P..X....

It would be nice if it could be split like:

Test1.hx: ....PP
Test2.hx: PPXX....
Test3.hx: .P..X....

I looked into the reporter code, that could be done with a custom reporter. But first we need the file name to be stored in the Spec class

[nodejs] unmeaningful error

package;

import buddy.*;
using buddy.Should;

class RunTests extends SingleSuite
{

    public function new() {
        for(folder in sys.FileSystem.readDirectory('nonexistent')) {
            describe(folder, {
                it('should be $folder', {
                    true.should.be(true);
                });
            });
        }

    }
}

The above code on nodejs fails with:

/Users/kevin/Codes/test/bin/node/tests.js:254
        runner.haveUnrecoverableError(err);
              ^

TypeError: Cannot read property 'haveUnrecoverableError' of null
    at process.<anonymous> (/Users/kevin/Codes/test/bin/node/tests.js:254:8)
    at emitOne (events.js:77:13)
    at process.emit (events.js:169:7)
    at process._fatalException (node.js:211:26)

which is not meaningful.

Running the same code on neko gives you some hint about the error of reading a non-existent directory though.

Feature Request: Allow `err(e:Dynamic)` as a second parameter to an `it` function.

It'd be nice to be able to wire it right up as an error handler on promises and callbacks.

Then the test would fail with a nice error message when the error callback is called.

Something like this:

            it("should make a GET request with promise", function(done, err) {
                var p = c.getJson("/hello_world");
                p.then(function(r) {
                    r.statusCode.should.be(200);
                    r.data.title.should.be('Hello World');
                    done();
                });
                p.catchError(err);  // <-- This would fail the test with a message as passed to err()
            });

Feature request: Don't stop at first failed test

For each describe session, it seems that once the first test fails, the section tests stop being executed. This is very annoying when you introduce a big change - specially if your program takes a while to compile.

Thanks for the great work!

Stack traces for exceptions

I tried to do this:

try {
    #if utest
    Assert.results = new List<Assertation>();
    #end
    spec.run(done, status);
    if (!spec.async) done();
}
catch (e : Dynamic) {
    var stackTrace = CallStack.toString( CallStack.exceptionStack() );
    status(false, Std.string(e) + stackTrace);
}

But the async code swallows up the exception stack and I'm not familiar enough with promhx to know where to look next :)

run only one test feature

I'm writing more tests with buddy at the moment and like it a lot !
One useful feature that I use in mocha is the "only" function, described here:
http://mochajs.org/#exclusive-tests

This allows to focus on only one test or test suite while debugging.
If you think it can make a good addition, I can try implementing it.

Thanks

should.beType( String )

It would be handy to have this check, just using Std.is(). And obviously the negative too: should.not.beType().

I'm not precious about the exact syntax or wording if you think of something better :)

Python code generation bug in switch statement

In SuitesRunner.hx the following function is defined.

private function isSync(funcs : Iterable) : Bool {
for (f in funcs) switch f {
case Async(): return false;
case Sync(
):
}
return true;
}

On my Windows Server 2008 machine, this gets turned into the below in python:

def isSync(self,funcs):
# C:\HaxeToolkit\haxe\lib\buddy/2,2,0/buddy/SuitesRunner.hx:306
# C:\HaxeToolkit\haxe\lib\buddy/2,2,0/buddy/SuitesRunner.hx:306
tmp = HxOverrides.iterator(funcs)
while tmp.hasNext():
if ((tmp.next().index) == 0):
return False
elif ((tmp.next().index) == 1):
pass
else:
pass
# C:\HaxeToolkit\haxe\lib\buddy/2,2,0/buddy/SuitesRunner.hx:310
return True

When run I get this error do to the multiple tmp.next() calls:

File "C:\Users\administrator.HOSTINTEGRATION\Desktop\Haxe\solidfire-sdk-haxe\bin\RunTests.py", line 8040, in isSync
elif ((tmp.next().index) == 1):
AttributeError: 'NoneType' object has no attribute 'index'

Updating the code to the following fixes the issue:

private function isSync(funcs : Iterable) : Bool {
for (f in funcs) switch f {
case Async(_): return false;
default:
}
return true;
}

This does not happen on my Windows 10 PC or on Mac.

Using Python 3.5 and Buddy 2.2.0, and Haxe 3.2 on all machines.

I will open a bug with the haxe project, but I wasnt sure if you wanted to work around the issue in the mean time.

-dce full breaks tests

-dce full breaks tests

node js_test.js
/home/as3boyan/HIDE-atom-shell/bin/js_test.js:166
            var $it1 = b.suites.iterator();
                                ^
TypeError: Cannot call method 'iterator' of undefined
    at includeMode (/home/as3boyan/HIDE-atom-shell/bin/js_test.js:166:24)
    at Object.buddy.SuitesRunner (/home/as3boyan/HIDE-atom-shell/bin/js_test.js:174:3)
    at Function.TestMain.main (/home/as3boyan/HIDE-atom-shell/bin/js_test.js:92:15)
    at /home/as3boyan/HIDE-atom-shell/bin/js_test.js:882:10
    at Object.<anonymous> (/home/as3boyan/HIDE-atom-shell/bin/js_test.js:883:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

compile time error with multiple libs using buddy

I have 2 libs using buddy. The first one include the second one for its test using a -lib flag. When I run the tests I get the following errors:

/usr/lib/haxe/lib/buddy/0,9,0/buddy/Buddy.hx:3: characters 2-11 : Invalid package : test.unit should be unit

Both libs have a test/unit folder where the tests are. If I delete the tests from the second lib, everything works fine.

error occurring in 0.12

after upgrading to 0.12.0 an error gets thrown when I try to compile and run:

output:
usr/lib/haxe/lib/buddy/0,12,0/buddy/BuddySuite.hx:202: characters 33-53 : Invalid field access : include
/usr/lib/haxe/lib/buddy/0,12,0/buddy/BuddySuite.hx:153: characters 2-43 : Called from
test/TestMain.hx:10: lines 10-14 : Called from
:1: character 0 : Called from
test/TestMain.hx:8: lines 8-16 : Called from
:1: character 0 : Called from
/usr/lib/haxe/std/neko/_std/Type.hx:108: characters 9-25 : Called from
/usr/lib/haxe/lib/buddy/0,12,0/buddy/GenerateMain.hx:111: characters 17-62 : Called from
?:1: characters 1048575-8796094070782 : Called from
Aborted
[Finished in 0.5s with exit code 1]

implementing should.equal for deep equality

I've started to use Buddy for a new project, it's great so far !

One of the assertions I use when doing BDD in JS is "equal" or "eql", comparing 2 objects recursively by value.
Is it something which can be done ?

Thanks !

Python Issue - binding to check that an exception is thrown

It appears that binding affects the order parameters are passed into a function in python when you have optional parameters and a PosInfos param.

Here is some example code to show the problematic behavior:

import buddy.*;
using buddy.Should;
using haxe.PosInfos;

class Sandbox extends BuddySuite
{
    public function new()
    {
        describe("Bind",
        {
            it("should bind properly",{

                Sys.println("calling without bind");
                showBindProblem();

                Sys.println("\ncalling with bind");
                showBindProblem.bind().should.throwAnything();

                Sys.println("\ncalling with bind and an empty array");
                showBindProblem.bind([]).should.throwAnything();

            });
        });
    }

    private function showBindProblem(?args:Array<Dynamic>,?p:haxe.PosInfos)
    {
        Sys.println("args: " + args);
        Sys.println("p: " + p);
    }
}

This produces the following output:

calling without bind
args: null
p: { className : Sandbox, fileName : Sandbox.hx, lineNumber : 14, methodName : new }

calling with bind
args: { className : Sandbox, fileName : Sandbox.hx, lineNumber : 17, methodName : new }
p: null

calling with bind and an empty array
args: []
p: { className : Sandbox, fileName : Sandbox.hx, lineNumber : 20, methodName : new }

Problems with tink_core's Future.ofMany

libs: -lib tink_core -lib buddy

Main.hx

import buddy.*;

class Main implements Buddy<[
    Test,
]> {}

Test.hx

import buddy.*;
using tink.CoreApi;

class Test extends BuddySuite {
    public function new() {
        Future.ofMany([
            Future.sync(Success(Noise)),
            Future.sync(Success(Noise)),
        ]);
        describe('Test', {
            it('dummy', {});
        });
    }
}

The above code fails with:

/Users/kevin/Development/haxelib/tink_core/git/src/tink/core/Future.hx:77: characters 18-30 : tink.core.Future<Array<ofMany.A>> should be tink.core.Future<A
rray<fromMany.A>>
/Users/kevin/Development/haxelib/tink_core/git/src/tink/core/Future.hx:77: characters 18-30 : Type parameters are invariant
/Users/kevin/Development/haxelib/tink_core/git/src/tink/core/Future.hx:77: characters 18-30 : ofMany.A should be fromMany.A
/Users/kevin/Development/haxelib/tink_core/git/src/tink/core/Future.hx:78: characters 11-14 : tink.core.Future<Array<ofMany.A>> should be tink.core.Future<A
rray<fromMany.A>>
/Users/kevin/Development/haxelib/tink_core/git/src/tink/core/Future.hx:78: characters 11-14 : Type parameters are invariant
/Users/kevin/Development/haxelib/tink_core/git/src/tink/core/Future.hx:78: characters 11-14 : ofMany.A should be fromMany.A

Make sure not to put the two classes in a same file, otherwise it will work.
Not sure if it is Haxe problem or buddy's or tink_core's problem...

cc @back2dos

Neko tests failing - buddy: [0.11.1]

Getting this. It used to work, some test I added seems to have caused it, but I've not been able to hunt it down. Works fine in flash.

...Called from ? line 1
Called from buddy/GenerateMain.hx line 117
Called from buddy/SuitesRunner.hx line 30
Called from promhx/Promise.hx line 102
Called from promhx/base/AsyncBase.hx line 221
Called from promhx/base/AsyncBase.hx line 148
Called from promhx/base/EventLoop.hx line 73
Called from promhx/base/EventLoop.hx line 57
Called from promhx/base/AsyncBase.hx line 158
Called from promhx/base/AsyncBase.hx line 145
Uncaught exception - Invalid field access : length

Any guidance as to what to look for?

Option to limit AutoIncluder to only certain packages

I'm trying to test buddy on an existing project but [this line](https://github.com/ciscoheat/buddy/blob/master/src/buddy/tools/AutoIncluder.hx#L39] results in hundreds of compiler errors. This includes things like:

  • "neko" / "php" packages being entered into when that is not the current platform. (3rd party code, not the current platform).
  • 3rd party libraries with broken but unreferenced code causing compiler errors. (In my case, an old version of thx that I am still using).

etc. Because these errors occur at macro time they are particularly difficult to debug.

Can we change the build macro to have an optional "includePackages" argument? The usage would remain the same if you just use implements Buddy, but for poor souls such as myself we could call the build macro manually with just the package we wish to include.

I'm happy to create a pull request if you are okay with it.

Disable threading by default

It's a little unexpected that buddy 1.0+ now runs the tests on threads by default. It becomes harder to debug, and furthermore, there is some testing that needs to be done on the main thread, but I can't figure out how to disable threading. Is there any way to do it?

minor features

Hi,

  • please add some color to the terminal reporter.
  • please allow comparing arrays with should.be (right now, it is by reference only)
    • it is usable with array.should.containExactly

[C#] Doesn't report tests after first thrown exception

To reproduce:

class Main {

    static function main() {
    var reporter = new ConsoleReporter();
    var runner = new SuitesRunner([new Test()], reporter);
    runner.run();
    }
}

class Test extends BuddySuite {

  public function new():Void {
    var x = 1;

    describe("test one", {

      it("fail", {
        throw "fail";
      });

      it("pass", {
        x.should.be(1);
      });

    });
  }
}

Neko output (correct):

X.
test one
  fail (FAILED: fail)
    @ Main.hx:26
  pass (Passed)
2 specs, 1 failures, 0 pending

C# output (missing report of second step):

X.
test one
  fail (FAILED: fail)

Unhandled Exception: System.NullReferenceException: Object reference not set to
an instance of an object.
   at promhx.base.AsyncBase__handleError_159__Fun`1.__hx_invoke1_o(Double __fn_f
loat1, Object __fn_dyn1)
   at promhx.base.AsyncBase__handleError_176__Fun`1.__hx_invoke0_o()
   at promhx.base.EventLoop.f()
   at promhx.base.AsyncBase`1.immediateLinkUpdate[A,B](AsyncBase`1 current, Asyn
cBase`1 next, Function f)
   at promhx.Promise`1.then[A](Function f)
   at buddy.SuitesRunner.run()
   at EntryPoint__Main.Main()

Note that wrapping it in a try/catch will not solve the issue, but only prevent the stack trace to be logged.

Pending async tests

I am setting up many tests (about 60) that are pending for now, but will be async tests once implemented.

// PENDING:
it("Should send an email to that teacher, with a pre-approved invitation", function () {});

// PASS:
it("Should send an email to that teacher, with a pre-approved invitation", function (done) { done(); });

I feel these should both be pending. Do you agree?

Ideas for reporters.

I'm using Buddy primarily on a code base that targets Flash, so accept my twisted perspectives with that in mind. :)

I eventually want to get my Buddy specs running in Continous Integration, and I'm also a big fan of command line test runners.

The flash tests, though, need to run in the Flash Debugger (I use the open command on my Mac).

It'd be great if all the tests, no matter the target, reported their results back to a central command line test runner, who was then in charge of displaying the results in a common manner.

I've recently done some testing where my tests work against a node.js server running along side them. It seems to work well enough (once all the cross-origin stuff was worked out..) Perhaps a test runner could start a server and then launch the individual target's test runners. Those 'child' runners would communicate their results back to the server on a well-known port which would then handle the job of actually displaying the results on screen (or writing them to file in the JUnit-style for CI!)

unit test macros

Hi,
is unit testing macros supported ?
If it is, how would you go about it ?

Thanks

Can't compile when async test in "it"

it("should", function(done)done()); this statement cause following compile-time bug

/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/base/AsyncBase.hx:167: characters 16-21 : Can't create thread from within a macro
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/base/AsyncBase.hx:186: characters 20-40 : Called from
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/base/EventLoop.hx:60: characters 24-28 : Called from
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/base/EventLoop.hx:77: characters 12-15 : Called from
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/base/AsyncBase.hx:176: lines 176-188 : Called from
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/Promise.hx:120: characters 7-26 : Called from
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/base/AsyncBase.hx:256: characters 30-49 : Called from
/usr/lib/haxelib/promhx/1,0,21/src/main/promhx/Promise.hx:102: characters 8-36 : Called from
/usr/lib/haxelib/buddy/0,18,1/buddy/SuitesRunner.hx:31: lines 31-43 : Called from
/usr/lib/haxelib/buddy/0,18,1/buddy/GenerateMain.hx:195: characters 4-16 : Called from
?:1: characters 1048575-8796094070782 : Called from
Aborted
Build failed

Comparison with Dynamic typing throws error

Not sure how if the title correctly describes the issue but while trying to replicate a similar issue I'm seeing in Haxe 3.2 rc-1 I realized something like the following is failing in the 3.1.3.

 it("should pass", {
//test will pass if :Dynamic is removed
  var arr:Dynamic,
      fn;
  arr = new Array<String>();

  fn = function(){
    return arr;
  }
 trace(arr == fn()); //true
  arr.should.be(fn());
/*
throws:
 should pass (FAILED: Invalid call)
      @ /usr/lib/haxe/lib/buddy/0,17,0/buddy/internal/SuiteBuilder.hx:43
      @ /usr/lib/haxe/lib/buddy/0,17,0/buddy/internal/SuiteRunner.hx:179
*/
});

I'll try to post the 3.2 issue when I can although that may just be a bug in 3.2. It does throw the same error though.

1.0.1 Errors

I can break this out into separate issues if you like but I figured I'd just give a summary of what I've seen first

  • Initial run gave me /usr/local/lib/haxe/lib/buddy/1,0,1/buddy/internal/GenerateMain.hx:179: characters 3-36 : Type not found : SuitesRunner
    • Importing this into my main class fixed this.
  • For CPP I'm getting /usr/local/lib/haxe/lib/buddy/1,0,1/buddy/BuddySuite.hx:12: characters 7-22 : Type not found : hxcpp.StaticStd
  • For Neko I used to be able to run the tests using --interp this doesn't seem to work anymore
  • For js, neko & php I'm getting test failures that used to pass. I'm pretty sure they weren't false positives in the previous version but I'll investigate further on my end to be sure.

PHP Async Support

I have interest in making async tests work on PHP.

I understand that PHP doesn't support true async, but my use case is:

  • I have some code that I want to compile to Neko, PHP and JS
  • Because of JS, I'm using async style code, and Neko and PHP just "pretend"
  • They use async method signiatures, but actually run synchronously...

Anyway, this is all fine, but the async tests don't work because promhx doesn't support PHP.

So my question: what would be the best approach to support pseudo-async PHP tests in Buddy:

  1. Work around the need for promhx on PHP
  2. Go ask @jdonaldson how to make Promhx work on PHP?

before is not executed for each spec if outside a describe

I have the following test:

before(function () {
  //initialize code
})

describe('#function', function () {
   it('should do stuff');
});

describe('#anotherFunction', function () {
  it('should do other stuff');
});

The initialisation code in before seems to not be called before each 'it', but only before each 'describe'. If I duplicate the before in each describe it works fine.

Is it the normal behaviour ? In mocha there is before and beforeEach, maybe that's what is missing ?

By the way, I've started using utest.Assert and it works great, thanks !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.