Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add seq/par and hook #83

Merged
merged 39 commits into from
Mar 20, 2019
Merged

add seq/par and hook #83

merged 39 commits into from
Mar 20, 2019

Conversation

safareli
Copy link
Member

@safareli safareli commented Jan 10, 2019

fix #80
fix #43
fix #44 (any m can be lifted into Spec so you can lift Effect too)
fix #63
fix #68 (in the end user can hoist Either to Aff)

it might somewhat fixes #73 haven't looked into it yet


Initially I tired to rebase #52 on top of #82 but using the approach taken in #52 it was not possible to define afterAll and nesting of hooks was not possible too. So instead I ported this version from hspec.

things left to do:

  • need to fix reporter to handle case when there is nesting of describe in parallel (see logs of delaySpecExample)
  • add docs of hooks (probably copy and modify from hspec)

the reason is that using generic instance results in:

```
/dev/purescript-spec/output/Data.Generic.Rep.Show/index.js:13
var GenericShowArgs = function (genericShowArgs) {
                               ^

RangeError: Maximum call stack size exceeded
    at new GenericShowArgs (/dev/purescript-spec/output/Data.Generic.Rep.Show/index.js:13:32)
    at Object.genericShowArgsArgument (/dev/purescript-spec/output/Data.Generic.Rep.Show/index.js:20:12)
    at showGroup (/dev/purescript-spec/output/Test.Spec/index.js:241:228)
    at showGroup (/dev/purescript-spec/output/Test.Spec/index.js:241:456)
```
@safareli
Copy link
Member Author

This is ready for review @felixmulder @owickstrom. tomorrow will try to fix issue with reporter (about parallel nested describes) and add some docs. let me know if there are some comments/suggestions.

@felixmulder
Copy link
Collaborator

Cool! Won't have time to review today - but hopefully during the weekend 🙂

as they are not Aff specific any more
now consoleReporter and specReporter need to coordinate tests which are running in parallel
@safareli
Copy link
Member Author

The issue I have now is that consoleReporter and specReporter need to handle case like this:

describe "a" $ parallel do
  it "a.1" $ delay $ Milliseconds 500.0
  it "a.2" $ delay $ Milliseconds 500.0
  describe "b" do
    it "b.1" $ delay $ Milliseconds 500.0
    it "b.2" $ delay $ Milliseconds 500.0

so a reporter will get events in this order, which is messing output:

Suite a
Test a.1
Test a.2
Suite a.b
Test a.b.1
Test a.b.2
Pass a.1 + TestEnd a.1
Pass a.2 + TestEnd a.2
Pass a.b.1 + TestEnd a.b.1
Pass a.b.2 + TestEnd a.b.2
SuiteEnd a.b
SuiteEnd a

solution is to make reporters more "advanced", by showing currently running tests with some spinner, and then once they finish update corresponding indicators, ideally so that if a test is logging something to console, it's not interfering to the test output (I haven't done such things in terminal and some suggestions/helpful links, would be great help for fixing this issue)

@safareli
Copy link
Member Author

AFAICT without some kind of mocking/monkey patching, a reporter has no way to know if a running test logged something to terminal. If that's true, we have 2 options:

  1. ignore case when some test logs to console and be ok that it will mess output.
  2. fancy reporters like consoleReporter and specReporter will take Bus (Path, String) as argument and they will be watching for messages and safely printing them so output is not messed up.

I would at first go with option 1 and then probably in new PR implement option 2 so, before that using console.log in parallel tests will mess output at bit.

@safareli
Copy link
Member Author

safareli commented Jan 15, 2019

so i was able to update spec/console reporters to handle parallel execution:

screen recording 2019-01-15 at 12 22 21 pm
screen recording 2019-01-15 at 12 21 43 pm 1

But, :(

if a line printed to console is wrapped, then redraw is messed up and output looks like this:

screen shot 2019-01-15 at 12 33 00 pm

screen shot 2019-01-15 at 12 32 18 pm

this particular issue can be fixed in countLines function, if reporter subscribes to width of terminal (with process.stdout.getWindowSize and process.stdout.on("resize")) but I think it might not work for all terminals&OS combinations.

so at this point I feel that the "redrawing" terminal output is not a good idea, so will try to simplify reporters and will log things to console which are not going to change, it would mean that if you are running multiple tests in parallel you wouldn't see there output until whole all of them are finished.

@felixmulder
Copy link
Collaborator

Wow, awesome work @safareli !

You've really put time into this.

@felixmulder
Copy link
Collaborator

Quite a large PR - but I couldn't see anything that raised a red flag with me. @owickstrom, maybe you'd like to review as well?

@safareli
Copy link
Member Author

You've really put time into this.

Yeah, was working on it for about a week, we are using this lib at @f-o-a-m, and we wanted to have this features, so it was sort of my "task".

with `exit: false` and you can get test results
with `[]` as reporters you can get no reporting
so removed runSpec,runSpec' and renamed run,run' to runSpec and runSpecM
for example here all types are derived by compiler:
```
foo :: forall t19. Monad t19 => SpecT Aff Unit t19 Unit
foo = it "foo" $ delay $ Milliseconds 100.0

baz :: forall t17 t18 t19. Monad t19 => SpecT t18 t17 t19 Unit
baz = describe "baz" $ pure unit

fix :: forall t18 t19. Monad t19 => MonadThrow Error t18 => SpecT t18 Unit t19 Unit
fix = it "fiz" $ 1 `shouldEqual` 1
```
vs beofre you would get huge `WriterT ...` type.
@safareli
Copy link
Member Author

It would be great if someone could check changes made in documentation.

@owickstrom
Copy link
Collaborator

I'll have a look when I'm back from vacation. Thanks for your effort on this @safareli!

Copy link
Collaborator

@owickstrom owickstrom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of cool stuff going on, I hope I didn't miss anything. Mostly my comment about compatibility that I would stress, and perhaps the test.

Otherwise, really awesome work! 🎉


-- | Run the spec with the default config
run
runSpec
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think runSpec is a better name, but can we for compatibility reasons also have run? As an alias of runSpec, perhaps with a deprecation Warn constraint?

it "supports async" do
res <- delay (Milliseconds 10.0) *> pure 1
res `shouldEqual` 1
where
runSpecFocused t = discardUnfocused (execWriter $ un SpecT t) <#> bimap (const unit) (un Item >>> _.isFocused)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runSpecFocused, if I'm not misunderstanding, isn't running the full runSpec machinery, like this test did before. It seems it's collecting a tree structure of Maybe Bool values for isFocused. Would it be possible to rewrite this to use runSpec (or some underlying function) to exercise the runner module?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most I could do is to add collect let me know if there is something you think is worth adding/changing.

@safareli
Copy link
Member Author

safareli commented Feb 7, 2019

Besides what was commented as part of the review I have change type of hoistSpec and mapSpecTree so the type in which SpecTrees are accumulated can also be changed, it can be useful for example if some part of test is using Spec type (which uses Identity) and then you want to use it in some SpecT with other monad like this: hoistSpec (un Identity >>> pure) (const identity) someTest

@safareli
Copy link
Member Author

safareli commented Feb 7, 2019

After we merge this we should probably update ps-spec-* libs

  • purescript-spec-discovery because now one can interleave some monadic effect in test generation the discover can have signature like this: discover :: MoandEffect m => String -> SpecT g i m Unit.
  • purescript-spec-reporter-xunit should be easy to update.
  • purescript-spec-quickcheck doesn't even depend on ps-spec and I guess needs no change.
  • purescript-spec-mocha updating this might not be trivial as we support parallel execution of tests but mocha doesn't. as I understand the main (if not only) benefit of using mocha for user is ability to run tests both in browser and node. it can be accomplished by striping suing console.log instead of process.stdout.write (this article can be useful for using colors etc in browser console output). so what i propose is to deprecate that and add make our built in reporters work in browser.

Let me know what others think about this.

@safareli
Copy link
Member Author

safareli commented Feb 7, 2019

Also do you think it's worth releasing this changes as v4.0.0-rc1 (maybe people can play with it and get some feedback) or we should go straight to v4?

@safareli
Copy link
Member Author

🏓 ping

@owickstrom
Copy link
Collaborator

I'm good with these last changes! And yeah, I think releasing an RC would be good.

@owickstrom
Copy link
Collaborator

@felixmulder you good with merging this?

@felixmulder felixmulder merged commit 003ef97 into purescript-spec:master Mar 20, 2019
@owickstrom
Copy link
Collaborator

👏

@safareli
Copy link
Member Author

Made a release v4.0.0-rc1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants