Scoping in BDD Syntax

I keep running into problems with scoping of variables in tests. I eventually get them working, but it’s been trial-and-error.

I either don’t understand the scoping/nesting rules particular to BDD syntax (or closures) or the rules are weird.

Here’s the latest example:

What drives me nuts is that I can debug(variables) and see the thingsToTest key that I want, but I can’t access variables.thingsToTest at the same spot.

What’s going on?

Thanks,
Jamie

I should have mentioned [TestBox v2.3.0].

What engine is this? Lucee or ACF?

I see your issue.

The problem is that this code: variables.thingsToTest = [“foo”,“bar”,“baz”];

Will not be available within the describe closures. They are only available at the it() level. Upon execution.

This is due to the fact that we execute the run() method to collect all the test data via describes. Once collected, we then execute the beforeAll and then closures execute. So if you need something before this sequence, just add it at the pseudo constructor level.

component extends=“testbox.system.BaseSpec”{

variables.thingsToTest = [“foo”,“bar”,“baz”];

}

Thanks for the explanation. That got my real-world example working.

Actually, I take it back. It makes the it() titles work (they do change for each loop iteration), but there then is a problem within the it() body: The values, changing with each iteration of the for loop, don’t really change inside the it(). (The value inside the it() always seems to reflect the last value in the loop.)

Suite and output: https://gist.github.com/jamiejackson/6feff13e529645922f5a1feb58c265e0

Because of your reply, I (almost) understand why this is happening (but only almost).

I also need a workaround, if someone knows of one.

FWIW, my engine is Lucee 4.x (latest stable).

Thanks,
Jamie

yes Jamie, that is to be expected. Closures are tricky sometimes to wrap around, no worries.

The issue is that you are statically binding the closures with the for loop. Meaning only the last binding takes effect. If you want to pass in data into the closure you must use the data argument to bind the spec with data at runtime. LIke this:

for ( var thing in thingsToTest ) {
it( title=thing & “test”, data={ thing = thing }, body=function() {
var thing = data.thing;
writeLog( thing & " start");
expect( writeLog( thing ) & thing ).toBe( thing );
writeLog( thing & " stop" );
});
}

Thanks for the reply.

I had high hopes, but my attempt, https://gist.github.com/jamiejackson/2d7ca7ace271128ac9e70aa046061b9d , isn’t working. It throws an error on the new line (45): variable [DATA] doesn’t exist

Did I misinterpret your reply?

Sorry, missing the data arugment in the closure: body=function( data )

That worked, Luis, thanks for the help.

Please also consider adding this, or something similar, to the documentation (to save the next poor sap a day or two):

https://gist.github.com/jamiejackson/24c64aa587f362e30d954266feb72e82

Side note: Are the GitBooks open-source?

Thanks,
Jamie

Yes, they are open source!

https://github.com/Ortus-Solutions/testbox-docs

You can submit pull requests. GitBook has a desktop editor you can use on your fork too or just edit the md files.