Re: [Unit tests] Mocking D objects
On Wednesday, 22 August 2018 at 08:33:36 UTC, Andrey wrote: Hello, I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects? For example: struct WebParser { // ... int download(string path) { SomeHttpClient client(path); auto result = client.request(path, 10, "Qwerty"); // ... return result.getSomething(); } } Here I want to replace struct/class SomeHttpClient from 3d-party library with my own test implementation. Something like this maybe: unittest { SomeMagicMockMechanism!(SomeHttpClient, MyMockedClient); WebParser parser; auto value = parser.download("www.example.com"); // uses MyMockedClient.request assert(value == 10); } You could also create an interface IHttpClient, a class HttpClientProductive which forwards the calls to SomeHttpClient and a class HttpClientDummy which can be instrumented which data it should return in unit test case. Both classes implements the interface. You also need a way to set the productive class for productive scenario and the dummy class in test scenario, e.g. via a factory class. There is a huge benefit using this way, you have a very loose coupling to SomeHttpClient. You can replace it very easily with another library. You could use this approach also for file system access, environment variables access, databases... Kind regards Andre
Re: Nested template arguments
On Wednesday, 22 August 2018 at 15:18:29 UTC, XavierAP wrote: On Wednesday, 22 August 2018 at 14:48:57 UTC, Alex wrote: Because it could be meant as the argument to some templates to the left. Like (foo!bar)!x Sure, it would be a coincidence, if both will work. However, templates are not something where you can simply imply the associative property, I think. Of course there isn't an associative property... But I was thinking that without brackets the parser could fall back to whatever default "left to right" precedence, as would happen with operators, which needn't be associative either. Ah... ok. Got your idea. No. This isn't possible because some symmetry of the operator is implied. https://wiki.dlang.org/Operator_precedence Chaining is explicitly not allowed, like in comparison operators :)
Re: Nested template arguments
On Wednesday, 22 August 2018 at 14:48:57 UTC, Alex wrote: Because it could be meant as the argument to some templates to the left. Like (foo!bar)!x Sure, it would be a coincidence, if both will work. However, templates are not something where you can simply imply the associative property, I think. Of course there isn't an associative property... But I was thinking that without brackets the parser could fall back to whatever default "left to right" precedence, as would happen with operators, which needn't be associative either.
Re: Nested template arguments
On Wednesday, 22 August 2018 at 14:30:39 UTC, XavierAP wrote: Why foo!bar!x is not understood as foo!(bar!x) but instead gives an error "multiple ! arguments are not allowed"? Precisely because multiple "!" can never belong to the same instantiation, why does the parser not understand without needing brackets that the rightmost template should be nested as the argument for the next one to the left? Because it could be meant as the argument to some templates to the left. Like (foo!bar)!x Sure, it would be a coincidence, if both will work. However, templates are not something where you can simply imply the associative property, I think.
Nested template arguments
Why foo!bar!x is not understood as foo!(bar!x) but instead gives an error "multiple ! arguments are not allowed"? Precisely because multiple "!" can never belong to the same instantiation, why does the parser not understand without needing brackets that the rightmost template should be nested as the argument for the next one to the left?
Re: Test if variable has void value
On Wednesday, 22 August 2018 at 13:50:07 UTC, Andrey wrote: Hello, How to test if variable has void value? string text = void; if(text == void) { writeln("Is void"); } Tried this: if(is(text == void)) but doesn't work. You can't. When using a void initializer the actual value is garbage until initialized properly, and that garbage can look like anything including a valid instance. So if the flow of your program can't guarantee that the value has been initialized at a certain point, you'll have to track it yourself some way. Nullable may be of help: https://dlang.org/phobos/std_typecons.html#Nullable
Test if variable has void value
Hello, How to test if variable has void value? string text = void; if(text == void) { writeln("Is void"); } Tried this: if(is(text == void)) but doesn't work.
Re: Templated operator overloading
On Wednesday, 22 August 2018 at 12:36:39 UTC, Simen Kjærås wrote: Since both your opOpAssigns match equally, the compiler throws up. The solution is to add some sort of restriction: This doesn't happen apparently: the operator has a left and a right side, even if both types define the operator, only one of them is on the left at each call. It works now after Ali corrected my stupid syntax :)
Re: Templated operator overloading
On Wednesday, 22 August 2018 at 13:20:01 UTC, aliak wrote: "void opOpAssign(string op, T)(ref Tthis, const ref T x)" looks like the wrong signature for opOpAssign. Oh I'll put on my stupid hat now... I realize I had copy-pasted the wrong syntax from the global function attempt, but I swear I thought I had re-typed and tested the right one... It's working now :)
Re: Templated operator overloading
On Wednesday, 22 August 2018 at 11:58:25 UTC, XavierAP wrote: I've been trying some things to template operator overloads. The reason is that I want very similar code for different types, but I can't use polymorphism, as they're structs rather than classes. Perhaps this choice is not as advantageous as I think, and I may change this design from structs to classes, or else the code duplication would be small and never subject to change. But now I'm just trying for the sake of learning to find out what works or not in terms of templated operator overloading, and whether the reason something doesn't work is by design and if mentioned in the specification, or just an arbitraty result of some unspecified parsing/lowering step order, or it depends on the compiler (I'm using dmd). [...] "void opOpAssign(string op, T)(ref Tthis, const ref T x)" looks like the wrong signature for opOpAssign. THink it needs to be: void opOpAssign(string op, T)(const ref T x) Then: mixin template operator! { void opOpAssign(string op, T)(const ref T x) { writeln(this, op, x); } } struct S1 { mixin operator; } struct S2 { mixin operator; } Cheers, - Ali
Re: Templated operator overloading
On Wednesday, 22 August 2018 at 11:58:25 UTC, XavierAP wrote: When I want to have the same operator overloading code in both types however, I can't make it work: From https://dlang.org/spec/operatoroverloading.html#binary: "the one with the ‘better’ match is selected. It is an error for both to equally match." Since both your opOpAssigns match equally, the compiler throws up. The solution is to add some sort of restriction: struct S1 { mixin opOver; } struct S2 { mixin opOver; } mixin template opOver() { auto opOpAssign(string op, T)(T rhs) if (T.stringof > typeof(this).stringof) { // Here import std.stdio; writeln(this, op, rhs); } } unittest { S1 a; S2 b; a += b; } And a final try with a global templated function instead of a mixin template: // private void opOpAssign(string op, Tthis, T)(ref Tthis that, const ref T x) This syntax would either enable the definition of operators on builtin types that shouldn't have them, or be perceived as inconsistent, so invasive operator overloading is used in D instead. -- Simen
Templated operator overloading
I've been trying some things to template operator overloads. The reason is that I want very similar code for different types, but I can't use polymorphism, as they're structs rather than classes. Perhaps this choice is not as advantageous as I think, and I may change this design from structs to classes, or else the code duplication would be small and never subject to change. But now I'm just trying for the sake of learning to find out what works or not in terms of templated operator overloading, and whether the reason something doesn't work is by design and if mentioned in the specification, or just an arbitraty result of some unspecified parsing/lowering step order, or it depends on the compiler (I'm using dmd). Since there are in my case two similar types (below just a minimal dumb proof of concept), I want the operator(s) to work within the same type, or also with the other. The following code actually works, including type parameter inferrence, and const ref to avoid struct copying: // import std.stdio; struct S1 { void opOpAssign(string op, T)(const ref T x) { writeln(this, op, x); } } struct S2 {} void main() { S1 s1; S2 s2; s1 *= s2; } // When I want to have the same operator overloading code in both types however, I can't make it work: // private mixin template operator(Tthis) { void opOpAssign(string op, T)(ref Tthis, const ref T x) { writeln(this, op, x); } } struct S1 { mixin operator!S1; } struct S2 { mixin operator!S2; } void main() { S1 s1; S2 s2; s1 *= s2; // Error: s1 *= s2 is not a scalar s1.opOpAssign!"*"(s2); // Error: template test.S1.operator!(S1).opOpAssign cannot deduce function } // And a final try with a global templated function instead of a mixin template: // private void opOpAssign(string op, Tthis, T)(ref Tthis that, const ref T x) { writeln(that, op, x); } struct S1 {} struct S2 {} void main() { S1 s1; S2 s2; s1 *= s2; // Error: s1 *= s2 is not a scalar s1.opOpAssign!"*"(s2); // OK! } //
Re: How to map elements of a tuple?
On Wednesday, 22 August 2018 at 10:36:32 UTC, Andrey wrote: Hello, Is there a template/function/mixin... in the library that I can use to map elements of a tuple? object.foo(Mapper!myMapFunction(1, bool, "Qwerty", EnumedColor.Red)); where "Mapper" is this mapper and "myMapFunction" is a template function that I want to apply to each member in tuple. I know that there is std.algorithm.map but as I understand it is suitable only for arrays (types are the same). I believe this should be what you're looking for: import std.typecons; auto map(alias fn, T...)(Tuple!T arg) { import std.conv : text; import std.range : iota; import std.algorithm.iteration : joiner, map; return mixin(text("tuple(",T.length.iota.map!(i => text("fn(arg[",i,"])")).joiner(", "),")")); } unittest { import std.conv : to; auto a = tuple(1,2,"").map!(a => a.to!string); assert(a == tuple("1","2","")); } -- Simen
Re: D need an ORM library!
On Wed, 2018-08-22 at 06:14 +, binghoo dang via Digitalmars-d-learn wrote: […] > yeah, Diamond is great, but I think it will be more wonderful if > it's database ORM can be separated to a standalone project, > that's would be useful for the application that's is not WEB > oriented but need an ORM. Possibly, but possibly not. Django has an ORM, but SQLAlchemy happened as well. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: How to map elements of a tuple?
On Wednesday, 22 August 2018 at 10:36:32 UTC, Andrey wrote: Hello, Is there a template/function/mixin... in the library that I can use to map elements of a tuple? object.foo(Mapper!myMapFunction(1, bool, "Qwerty", EnumedColor.Red)); where "Mapper" is this mapper and "myMapFunction" is a template function that I want to apply to each member in tuple. I know that there is std.algorithm.map but as I understand it is suitable only for arrays (types are the same). Could you explain, how you mix a type "bool" and a value "Qwerty" in a single tuple? Especially, which value do you pass to you function, when the template parameter becomes bool?
How to map elements of a tuple?
Hello, Is there a template/function/mixin... in the library that I can use to map elements of a tuple? object.foo(Mapper!myMapFunction(1, bool, "Qwerty", EnumedColor.Red)); where "Mapper" is this mapper and "myMapFunction" is a template function that I want to apply to each member in tuple. I know that there is std.algorithm.map but as I understand it is suitable only for arrays (types are the same).
Re: Coreect way to create delegate for struct method.
On Tuesday, 21 August 2018 at 21:29:38 UTC, Andrey wrote: Hello, This is a code: (...) test.handler = &test.one; That's an internal pointer, and internal pointers are not allowed in structs precisely because of the issues you're running into: the pointer will be invalid after a move. You may be able to get it kind of working, but I'd recommend looking for another solution to your problem. This is one of those things that will come back to bite you later.
Re: D need an ORM library!
On Wednesday, 22 August 2018 at 06:14:40 UTC, binghoo dang wrote: On Tuesday, 21 August 2018 at 10:48:30 UTC, bauss wrote: Currently (When I get time again) working on implementing PostgreSQL and Sqlite support for Diamond. Mysql and Mssql should work out the box. https://github.com/DiamondMVC/Diamond Some examples will come later, unless you use the latest stable version of Diamond then you have examples for MySql, but the implementation changes with the next release. http://diamondmvc.org/docs/data/#database I wouldn't call it light-weight like you explain, because it does have the whole framework, but you could technically just strip out the part of compile it with the appropriate flags to exclude the parts you don't need like the webserver. Else take a look at https://github.com/buggins/hibernated and perhaps https://github.com/buggins/ddbc is enough. yeah, Diamond is great, but I think it will be more wonderful if it's database ORM can be separated to a standalone project, that's would be useful for the application that's is not WEB oriented but need an ORM. Diamond works without web though. You can disable all web features and simply just import the modules for the orm etc. The ORM was used to be standalone, but became a huge dependency, so was just integrated into it. I would suggest
Re: D need an ORM library!
On Wednesday, 22 August 2018 at 09:33:26 UTC, bauss wrote: I would suggest Accidentally pressed "Send", but as I was saying. I would suggest https://github.com/buggins/hibernated as an alternative.
Re: [Unit tests] Mocking D objects
On Wednesday, 22 August 2018 at 08:33:36 UTC, Andrey wrote: Hello, I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects? For example: struct WebParser { // ... int download(string path) { SomeHttpClient client(path); auto result = client.request(path, 10, "Qwerty"); // ... return result.getSomething(); } } Here I want to replace struct/class SomeHttpClient from 3d-party library with my own test implementation. Something like this maybe: unittest { SomeMagicMockMechanism!(SomeHttpClient, MyMockedClient); WebParser parser; auto value = parser.download("www.example.com"); // uses MyMockedClient.request assert(value == 10); } The language itself does not offer mocking capabilities. However, there are excellent libraries in Dub: https://code.dlang.org/packages/unit-threaded https://code.dlang.org/packages/dmocks -- Simen
Re: Auto keyword and when to use it
On Tuesday, 21 August 2018 at 21:37:00 UTC, QueenSvetlana wrote: I had a misunderstanding about the keyword auto because I wrongfully believed that it made the code like Python Exactly, you are thinking still like D is Python or also dynamically typed. :) You will get when compiling errors that Python wouldn't detect until run-time (or with your private methods). - A declaration with auto needs to include an initialization. - The code will be equivalent as if replacing "auto" with the inferred type. It is not left for later to check. I'm not terribly bothered btw by "Type = new Type()" but often type names get too long or include namespaces... "mylib.numeric.squareObjectWithPointyCorners = new mylib.numeric.squareObjectWithPointyCorners()"
[Unit tests] Mocking D objects
Hello, I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects? For example: struct WebParser { // ... int download(string path) { SomeHttpClient client(path); auto result = client.request(path, 10, "Qwerty"); // ... return result.getSomething(); } } Here I want to replace struct/class SomeHttpClient from 3d-party library with my own test implementation. Something like this maybe: unittest { SomeMagicMockMechanism!(SomeHttpClient, MyMockedClient); WebParser parser; auto value = parser.download("www.example.com"); // uses MyMockedClient.request assert(value == 10); }
Re: Coreect way to create delegate for struct method.
On Wednesday, 22 August 2018 at 07:03:02 UTC, Andrey wrote: but it is ugly... You can write a type that will hide it.
Re: Coreect way to create delegate for struct method.
On Wednesday, 22 August 2018 at 07:03:02 UTC, Andrey wrote: On Tuesday, 21 August 2018 at 22:52:31 UTC, Alex wrote: Maybe, like this: Thank you but here you use heap to create ab object. I want only on stack. I know that one can do this: test_handler.ptr = null; and in place of call this: handler.ptr = cast(void*)&this; but it is ugly... Hmm, any other ideas? Ok... Another try: ´´´ import std.stdio; struct Test { void opAssign(Test) { "performing assignment".writeln; this.handler = &(this.one); } void one() const { writeln("In handler: Address = ", &this, "; Text = ", text); } void execute() { text = "Inited!"; writeln("Before: Address = ", &this, "; Text = ", text); handler(); } void delegate() handler = void; string text = "NoValue"; } struct Qwerty { void prepare() { _test = Test(); } void execute() { _test.execute(); } private: Test _test = void; } void main() { Qwerty qwerty; qwerty.prepare(); qwerty.execute(); } ´´´
Re: Coreect way to create delegate for struct method.
On Tuesday, 21 August 2018 at 22:52:31 UTC, Alex wrote: Maybe, like this: Thank you but here you use heap to create ab object. I want only on stack. I know that one can do this: test_handler.ptr = null; and in place of call this: handler.ptr = cast(void*)&this; but it is ugly... Hmm, any other ideas?