digitalmars.D.announce - unit-threaded v0.7.45 - now with more fluency
- Atila Neves (27/27) May 05 2018 For those not in the know, unit-threaded is an advanced testing
- Johannes Loher (9/36) May 05 2018 Personally, I don't like that kind of "abuse" of operators at
- Dechcaudron (5/13) May 07 2018 I think I'm siding with Johannes here. Much as the overloads look
- Johannes Loher (14/29) May 07 2018 Fluent assertions have one major advantage over using pascalCase
- Nick Sabalausky (Abscissa) (10/30) May 08 2018 I don't think that's the issue. At least, it isn't for me.
- Cym13 (17/51) May 08 2018 I wouldn't say it's an abuse, the dot means exactly the same
- Nick Sabalausky (Abscissa) (21/24) May 08 2018 No, it really doesn't mean the same thing at all. Not when you look away...
- Jacob Carlborg (8/10) May 09 2018 It scales better. This way only one "should" function is needed and one
- Dechcaudron (5/19) May 08 2018 Okay, I think I see your point, although it looks to me the added
- bauss (4/49) May 09 2018 I agree with this. If the comments weren't added, nobody reading
For those not in the know, unit-threaded is an advanced testing library for D that runs tests in threads by default. It has a lot of features: http://code.dlang.org/packages/unit-threaded New: * Bug fixes * Better integration testing * unitThreadedLight mode also runs tests in threads * More DDoc documentation (peer pressure from Adam's site) * Sorta kinda fluent-like asserts On the new asserts (should and should.be are interchangeable): 1.should == 1 1.should.not == 2 1.should.be in [1, 2, 3] 4.should.not.be in [1, 2, 3] More controversially (due to a lack of available operators to overload): // same as .shouldApproxEqual 1.0.should ~ 1.0001; 1.0.should.not ~ 2.0; // same as .shouldBeSameSetAs [1, 2, 3].should ~ [3, 2, 1]; [1, 2, 3].should.not ~ [1, 2, 2]; I also considered adding `.should ~=`. I think it even reads better, but apparently some people don't. Let me know? The operator overloads are completely optional. Atila
May 05 2018
On Saturday, 5 May 2018 at 13:28:41 UTC, Atila Neves wrote:For those not in the know, unit-threaded is an advanced testing library for D that runs tests in threads by default. It has a lot of features: http://code.dlang.org/packages/unit-threaded New: * Bug fixes * Better integration testing * unitThreadedLight mode also runs tests in threads * More DDoc documentation (peer pressure from Adam's site) * Sorta kinda fluent-like asserts On the new asserts (should and should.be are interchangeable): 1.should == 1 1.should.not == 2 1.should.be in [1, 2, 3] 4.should.not.be in [1, 2, 3] More controversially (due to a lack of available operators to overload): // same as .shouldApproxEqual 1.0.should ~ 1.0001; 1.0.should.not ~ 2.0; // same as .shouldBeSameSetAs [1, 2, 3].should ~ [3, 2, 1]; [1, 2, 3].should.not ~ [1, 2, 2]; I also considered adding `.should ~=`. I think it even reads better, but apparently some people don't. Let me know? The operator overloads are completely optional. AtilaPersonally, I don't like that kind of "abuse" of operators at all. I think it looks really unusual and it kind of breaks your "flow" when reading the code. Additionally, people, who don't know about the special behaviour the operators have in this case, might get really confused. I would much prefer it, if you used a more common fluent style (like 1.0.should.be.approximately(1.0001);). Anyways, thanks for working on this awesome project!
May 05 2018
On Saturday, 5 May 2018 at 15:51:11 UTC, Johannes Loher wrote:Personally, I don't like that kind of "abuse" of operators at all. I think it looks really unusual and it kind of breaks your "flow" when reading the code. Additionally, people, who don't know about the special behaviour the operators have in this case, might get really confused. I would much prefer it, if you used a more common fluent style (like 1.0.should.be.approximately(1.0001);). Anyways, thanks for working on this awesome project!I think I'm siding with Johannes here. Much as the overloads look nice, I don't really see the advantage over `shouldEqual`. Also, what's with `all.these.identifiers`? Any particular reason why you are more fond of them rather than of good ol' pascalCase?
May 07 2018
On Monday, 7 May 2018 at 09:19:31 UTC, Dechcaudron wrote:On Saturday, 5 May 2018 at 15:51:11 UTC, Johannes Loher wrote:Fluent assertions have one major advantage over using pascalCase assertions: There is no ambiuguity about the order of arguments. When using e.g. assertEquals, how do you know wheter is is supposed to be assertEquals(actual, expected), or assertEquals(expected, actual)? The first one is the only one that makes sense wirh UFCS, but it is not clear directly from the API. On top of that, some popular Frameworks (I‘m looking at you, JUnit...) do it exactly the other way round. With fluent assertions, you don‘t have this Problem, it is much more clear that it should be actual.should.equal(expected) and not expected.should.equal(actual), because it fits naturally in the chain of ufcs calls.Personally, I don't like that kind of "abuse" of operators at all. I think it looks really unusual and it kind of breaks your "flow" when reading the code. Additionally, people, who don't know about the special behaviour the operators have in this case, might get really confused. I would much prefer it, if you used a more common fluent style (like 1.0.should.be.approximately(1.0001);). Anyways, thanks for working on this awesome project!I think I'm siding with Johannes here. Much as the overloads look nice, I don't really see the advantage over `shouldEqual`. Also, what's with `all.these.identifiers`? Any particular reason why you are more fond of them rather than of good ol' pascalCase?
May 07 2018
On 05/07/2018 11:57 PM, Johannes Loher wrote:On Monday, 7 May 2018 at 09:19:31 UTC, Dechcaudron wrote:I don't think that's the issue. At least, it isn't for me. It's not a question of "assert equals" vs "should equal" (Though I am convinced by your argument on that matter). The question is: Why "should.equal" instead of "shouldEqual"? The dot only seems there to be cute. Not that I'm necessarily opposed to any of it (heck, I like cuteness in any sense of the word), it's just that: If the "~" thing is operator abuse, then I don't see how "should.equal", "should.not.be" etc, wouldn't fall into the same category.I think I'm siding with Johannes here. Much as the overloads look nice, I don't really see the advantage over `shouldEqual`. Also, what's with `all.these.identifiers`? Any particular reason why you are more fond of them rather than of good ol' pascalCase?Fluent assertions have one major advantage over using pascalCase assertions: There is no ambiuguity about the order of arguments. When using e.g. assertEquals, how do you know wheter is is supposed to be assertEquals(actual, expected), or assertEquals(expected, actual)? The first one is the only one that makes sense wirh UFCS, but it is not clear directly from the API. On top of that, some popular Frameworks (I‘m looking at you, JUnit...) do it exactly the other way round. With fluent assertions, you don‘t have this Problem, it is much more clear that it should be actual.should.equal(expected) and not expected.should.equal(actual), because it fits naturally in the chain of ufcs calls.
May 08 2018
On Tuesday, 8 May 2018 at 07:07:30 UTC, Nick Sabalausky (Abscissa) wrote:On 05/07/2018 11:57 PM, Johannes Loher wrote:I wouldn't say it's an abuse, the dot means exactly the same thing as everywhere else in the language. I'm way less fan of overidding ~ since that doesn't have that meaning in any other context. Without having actually used it, I like the composability over pascalCasing here, it looks like it fits nicely in a functional environment with things like aliases and partials I think, defining your own primitives naturally... Nothing one can't do with regular functions and pascalCased assertions, but it sounds like it would be way more verbose. It also sounds like it's easier on the implementation side since you never have to define both a "shouldSomething" and "shouldNotSomething", and that means as a user I can expect less bugs and better maintainance of the library. That said, it'll have to be field-tested to be sure.On Monday, 7 May 2018 at 09:19:31 UTC, Dechcaudron wrote:I don't think that's the issue. At least, it isn't for me. It's not a question of "assert equals" vs "should equal" (Though I am convinced by your argument on that matter). The question is: Why "should.equal" instead of "shouldEqual"? The dot only seems there to be cute. Not that I'm necessarily opposed to any of it (heck, I like cuteness in any sense of the word), it's just that: If the "~" thing is operator abuse, then I don't see how "should.equal", "should.not.be" etc, wouldn't fall into the same category.I think I'm siding with Johannes here. Much as the overloads look nice, I don't really see the advantage over `shouldEqual`. Also, what's with `all.these.identifiers`? Any particular reason why you are more fond of them rather than of good ol' pascalCase?Fluent assertions have one major advantage over using pascalCase assertions: There is no ambiuguity about the order of arguments. When using e.g. assertEquals, how do you know wheter is is supposed to be assertEquals(actual, expected), or assertEquals(expected, actual)? The first one is the only one that makes sense wirh UFCS, but it is not clear directly from the API. On top of that, some popular Frameworks (I‘m looking at you, JUnit...) do it exactly the other way round. With fluent assertions, you don‘t have this Problem, it is much more clear that it should be actual.should.equal(expected) and not expected.should.equal(actual), because it fits naturally in the chain of ufcs calls.
May 08 2018
On 05/08/2018 05:05 AM, Cym13 wrote:I wouldn't say it's an abuse, the dot means exactly the same thing as everywhere else in the language.No, it really doesn't mean the same thing at all. Not when you look away from the unimportant implementation details and towards the big picture: Normally, saying "x.y" denotes composition and membership: It means "y, which is a member of x". Saying "x.y" does NOT normally denote "The boundary between word 'x' and word 'y' in an english-grammared phrase". But with things like "should.not.be", it's very much NOT a composition/membership relationship: A "be" is not really a member/property/component/etc of a "not", except in the sense that that's how the english-like DSL is internally implemented. A "should" is not really something that is composed of a "not", except in the sense that that's how the english-like DSL is internally implemented. (IF it even is implemented that way at all. I didn't look, so for all I know it might be opDispatch.) I'm not saying that "should.not.be" OR "~" are abuses, I'm just saying whether or not they are, they're definitely both in the same category: Either they're both abuses or neither one is, because they both do the same thing: utilize use existing syntax for something other than the syntax's usual semantic meaning. Formal "operator overloading" isn't the only way to alter (or arguably abuse) a language's normal semantics.
May 08 2018
On Wednesday, 9 May 2018 at 04:40:37 UTC, Nick Sabalausky (Abscissa) wrote:On 05/08/2018 05:05 AM, Cym13 wrote:With UFCS I find that in my code a dot means "function composition" more often than "is a member of". Maybe it's just that I like writting in a functional style, but UFCS chains are very much endorsed by the language, so I wouldn't call it a stretch.[...]No, it really doesn't mean the same thing at all. Not when you look away from the unimportant implementation details and towards the big picture: [...]
May 09 2018
On Wednesday, 9 May 2018 at 10:37:52 UTC, Cym13 wrote:On Wednesday, 9 May 2018 at 04:40:37 UTC, Nick Sabalausky (Abscissa) wrote:I agree with this in this case.On 05/08/2018 05:05 AM, Cym13 wrote:With UFCS I find that in my code a dot means "function composition" more often than "is a member of". Maybe it's just that I like writting in a functional style, but UFCS chains are very much endorsed by the language, so I wouldn't call it a stretch.[...]No, it really doesn't mean the same thing at all. Not when you look away from the unimportant implementation details and towards the big picture: [...]
May 09 2018
On 2018-05-08 09:07, Nick Sabalausky (Abscissa) wrote:The question is: Why "should.equal" instead of "shouldEqual"? The dot only seems there to be cute.It scales better. This way only one "should" function is needed and one "not" function. Otherwise there would be a lot of duplication, i.e. "shouldEqual" and "shouldNotEqual". Hopefully the library can have a one generic implementation of "not", where it doesn't if the assertion is "equal", "be" or some other assertion. -- /Jacob Carlborg
May 09 2018
On Tuesday, 8 May 2018 at 03:57:25 UTC, Johannes Loher wrote:Fluent assertions have one major advantage over using pascalCase assertions: There is no ambiuguity about the order of arguments. When using e.g. assertEquals, how do you know wheter is is supposed to be assertEquals(actual, expected), or assertEquals(expected, actual)? The first one is the only one that makes sense wirh UFCS, but it is not clear directly from the API. On top of that, some popular Frameworks (I‘m looking at you, JUnit...) do it exactly the other way round. With fluent assertions, you don‘t have this Problem, it is much more clear that it should be actual.should.equal(expected) and not expected.should.equal(actual), because it fits naturally in the chain of ufcs calls.Okay, I think I see your point, although it looks to me the added verbosity and code complexity is not really worth it, provided you always use UFCS. But of course, that cannot be easily enforced I guess.
May 08 2018
On Saturday, 5 May 2018 at 15:51:11 UTC, Johannes Loher wrote:On Saturday, 5 May 2018 at 13:28:41 UTC, Atila Neves wrote:I agree with this. If the comments weren't added, nobody reading the code would have any idea what it actually does except for whoever wrote it.For those not in the know, unit-threaded is an advanced testing library for D that runs tests in threads by default. It has a lot of features: http://code.dlang.org/packages/unit-threaded New: * Bug fixes * Better integration testing * unitThreadedLight mode also runs tests in threads * More DDoc documentation (peer pressure from Adam's site) * Sorta kinda fluent-like asserts On the new asserts (should and should.be are interchangeable): 1.should == 1 1.should.not == 2 1.should.be in [1, 2, 3] 4.should.not.be in [1, 2, 3] More controversially (due to a lack of available operators to overload): // same as .shouldApproxEqual 1.0.should ~ 1.0001; 1.0.should.not ~ 2.0; // same as .shouldBeSameSetAs [1, 2, 3].should ~ [3, 2, 1]; [1, 2, 3].should.not ~ [1, 2, 2]; I also considered adding `.should ~=`. I think it even reads better, but apparently some people don't. Let me know? The operator overloads are completely optional. AtilaPersonally, I don't like that kind of "abuse" of operators at all. I think it looks really unusual and it kind of breaks your "flow" when reading the code.
May 09 2018