Re: unittest which uses a disk file

2019-01-16 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 17, 2019 at 12:58:20AM +, Victor Porton via Digitalmars-d-learn 
wrote:
> This way I would make data duplication (data files distributed with
> the source and the same data embedding as strings into my D sources).
[...]

You could use -J and string imports, perhaps?

In any case, if you only ever need to run unittests from within a main()
that never gets run by user code, then you could just version your
unittests like somebody else has suggested.  Then you could just make
assumptions about the current working directory and so on in your tests.


> Note that the source is multilingual (I am currently working on a
> multi-language bindings of a C library).

Not sure what this has to do with your question.


T

-- 
The two rules of success: 1. Don't tell everything you know. -- YHL


Re: unittest which uses a disk file

2019-01-16 Thread Victor Porton via Digitalmars-d-learn
This way I would make data duplication (data files distributed 
with the source and the same data embedding as strings into my D 
sources).


Note that the source is multilingual (I am currently working on a 
multi-language bindings of a C library).


Re: unittest which uses a disk file

2019-01-16 Thread Neia Neutuladh via Digitalmars-d-learn
On Wed, 16 Jan 2019 21:07:24 +, Victor Porton wrote:
> What is the rule for unittest which uses a file (containing example data
> for testing) available only in the source distribution, not in binary
> distribution?
> 
> I am writing a library.

The easy way of doing things is to define a version for your library's 
unittests. Like I might write:

version (EpubTest) unittest
{
writeEbookFile("test.epub");
}

And then in dub.sdl, I'd have the test configuration add
-version=EpubTest. Dub has support for this sort of thing, but I don't 
know the details offhand.

If you have extra dependencies or need extra environment setup, you might 
want to make a second dub package inside the same repository and give it a 
path-based dependency on your library. Normal people won't touch that 
second package, so you can do whatever you want there, and it's a good 
place to add another README.


Re: unittest which uses a disk file

2019-01-16 Thread Victor Porton via Digitalmars-d-learn
On Wednesday, 16 January 2019 at 21:07:24 UTC, Victor Porton 
wrote:
What is the rule for unittest which uses a file (containing 
example data for testing) available only in the source 
distribution, not in binary distribution?


I am writing a library.

The library has also a file main.d which is compiled only in 
DUB "application" configuration (I use this configuration 
solely for testing.)


Maybe I should put unittest { } into main.d not in the module 
which I test?


Also, what is the correct way to locate the file in the 
filesystem?


Also if I choose to put any tests in main.d, should these tests 
be within unittest { }? main.d is anyway meant to be compiled 
only in unittest mode, so I'm unsure.


Re: unittest which uses a disk file

2019-01-16 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jan 16, 2019 at 09:07:24PM +, Victor Porton via Digitalmars-d-learn 
wrote:
> What is the rule for unittest which uses a file (containing example
> data for testing) available only in the source distribution, not in
> binary distribution?
> 
> I am writing a library.
> 
> The library has also a file main.d which is compiled only in DUB
> "application" configuration (I use this configuration solely for
> testing.)
> 
> Maybe I should put unittest { } into main.d not in the module which I
> test?
> 
> Also, what is the correct way to locate the file in the filesystem?

There is no rule about this as far as I know, but generally speaking, my
advice is to avoid touching the filesystem from inside a unittest.  This
is not always possible, but where possible, I highly recommend
templatizing the File type so that you can substitute it with an
in-memory-only proxy in your unittest.  For example, instead of:

auto myFunc(Args...)(File fp, Args args) {
...
fp.rawWrite(...);
fp.rawRead(...);
... // etc.
}

unittest
{
auto testfile = File("testfile", "r+"); // <-- ugh
auto r = myFunc(testfile, ...);
...
}

do something like this instead:

auto myFunc(File = std.stdio.File, Args...)(File fp, Args args) {
...
fp.rawWrite(...);
fp.rawRead(...);
... // etc.
}

unittest
{
struct FakeFile {
string fakedata = "blah blah blah";
void[] rawRead(...) {
// copy fakedata into output buffer,
// etc.
}
... // ditto for any other method you might use
}
FakeFile testfile; // N.B.: no actual filesystem access
auto r = myFunc(testfile, ...);
...
}

This way, you can verify your code logic using only in-memory test data,
and you don't have to worry about polluting the filesystem with
temporary files, cleaning up after your unittest is done, setting up
paths, and all that messy stuff.

Better yet, separate your code logic so that accessing the filesystem
only happens in one place (e.g., in a user-facing API that takes
filenames, say), and encapsulate the file data as a generic data source,
so that the main logic of your code operates on the generic data source
(e.g., an input range of chars or bytes, or whatever other structure
most convenient for your logic) without any specific binding to
std.stdio.File.  Then it will be easy to pass in test data to your core
logic without needing to use File or the FakeFile hack above.

(The FakeFile hack is really only for testing low-level functions that
are actually intended to interact directly with the filesystem;
generally, I try to structure my code so that the "business logic" is
independent of the filesystem. It just operates on whatever abstract
data source is most convenient, whether a range, or even just a string
buffer, or whatever. This makes it easy to test with non-file data, and
avoids importing std.stdio everywhere (which IMO is a code smell).  It
also makes it easier to extend to other data sources in the future, like
network data.)


T

-- 
Those who don't understand Unix are condemned to reinvent it, poorly.


unittest which uses a disk file

2019-01-16 Thread Victor Porton via Digitalmars-d-learn
What is the rule for unittest which uses a file (containing 
example data for testing) available only in the source 
distribution, not in binary distribution?


I am writing a library.

The library has also a file main.d which is compiled only in DUB 
"application" configuration (I use this configuration solely for 
testing.)


Maybe I should put unittest { } into main.d not in the module 
which I test?


Also, what is the correct way to locate the file in the 
filesystem?