March 09, 2012
I'm testing a class that writes various things to a file, and I'd like to test that behavior, and I'm wondering what the standard solution here is.

In Python, I'd just use a StringIO class, for example. It seems sort of impractical to make std.outbuffer to work as a File (even if the file-like parameter is a template parameter, the outbuffer methods don't work like the File methods, as far as I can see), so I've concluded that using std.stdio.tmpfile is the way to go.

However, when I'm done with the tempfile, I'd like to have its contents as a string. It seems that File has no method for reading the entire file contents into a string, so I'd have to read and concatenate lines or chunks or something? Now, if the File returned by tmpfile had a name, I could use std.file.readText(). But no such luck (as far as I can see, tmpfile().name is null).

So I'm just wondering -- what's "the way" to do this sort of testing? And if it is along the lines of what I'm doing, is there some function/method for reading the contents of a File as a string?

(I guess this goes for much file-related functionality; much of it seems to be very related to file-names and actual files, rather than "file-like" objects, i.e., those with the appropriate methods...)

-- 
Magnus Lie Hetland
http://hetland.org

March 09, 2012
Magnus Lie Hetland:

> It seems that File has no method for reading the entire file contents into a string, so I'd have to read and concatenate lines or chunks or something?

There are std.file.read() and std.file.readText().

But I agree that std.stdio.File should have a readAll() method
:-) If you think this is a good idea, add it to Bugzilla.

Bye,
bearophile
March 09, 2012
On 2012-03-09 15:08:42 +0000, bearophile said:

> Magnus Lie Hetland:
> 
>> It seems that File has no method for reading the entire file contents into a string, so I'd have to read and concatenate lines or chunks or something?
> 
> There are std.file.read() and std.file.readText().

Yeah, I found those. I guess my post was a bit verbose, but the main point was that I have a File object, but no file name (because I'm using std.stdio.tmpfile() in a unit test), so std.file.read() and std.file.readText() are useless to me... :)

> But I agree that std.stdio.File should have a readAll() method
> :-) If you think this is a good idea, add it to Bugzilla.

Sure.

For now, though: What's The Way[TM] to write unit tests for code that writes to files? Use tmpfile and read/concatenate the file contents myself? Something else that's more practical? (I would have thought this kind of test would be common?-)

-- 
Magnus Lie Hetland
http://hetland.org

March 09, 2012
On Friday, March 09, 2012 16:48:33 Magnus Lie Hetland wrote:
> On 2012-03-09 15:08:42 +0000, bearophile said:
> > Magnus Lie Hetland:
> >> It seems that File has no method for reading the entire file contents into a string, so I'd have to read and concatenate lines or chunks or something?
> > 
> > There are std.file.read() and std.file.readText().
> 
> Yeah, I found those. I guess my post was a bit verbose, but the main
> point was that I have a File object, but no file name (because I'm
> using std.stdio.tmpfile() in a unit test), so std.file.read() and
> std.file.readText() are useless to me... :)

File has a name property. You can do something like

auto file = File.tmpfile();
auto filename = file.name;
auto str = readText(filename);

I do grant you though that it's a bit odd to need to get the file name and operate on that rather than operating on the File object. It works though, and is a lot cleaner than reading in the file line-by-line, if you don't actually need to do that.

- Jonathan M Davis
March 09, 2012
On Fri, Mar 09, 2012 at 01:42:01PM -0500, Jonathan M Davis wrote:
> On Friday, March 09, 2012 16:48:33 Magnus Lie Hetland wrote:
> > On 2012-03-09 15:08:42 +0000, bearophile said:
> > > Magnus Lie Hetland:
> > >> It seems that File has no method for reading the entire file contents into a string, so I'd have to read and concatenate lines or chunks or something?
> > > 
> > > There are std.file.read() and std.file.readText().
> > 
> > Yeah, I found those. I guess my post was a bit verbose, but the main
> > point was that I have a File object, but no file name (because I'm
> > using std.stdio.tmpfile() in a unit test), so std.file.read() and
> > std.file.readText() are useless to me... :)
> 
> File has a name property. You can do something like
> 
> auto file = File.tmpfile();
> auto filename = file.name;
> auto str = readText(filename);
> 
> I do grant you though that it's a bit odd to need to get the file name and operate on that rather than operating on the File object. It works though, and is a lot cleaner than reading in the file line-by-line, if you don't actually need to do that.
[...]

This seems like a strange limitation. Shouldn't it be possible to slurp the entire contents of an already-open file into a string? Perhaps a new method in File?

Also, using file.name is prone to race conditions in certain situations. (Not that it'd be a problem usually, but just sayin'.)


T

-- 
Designer clothes: how to cover less by paying more.
March 09, 2012
On Friday, March 09, 2012 11:34:07 H. S. Teoh wrote:
> On Fri, Mar 09, 2012 at 01:42:01PM -0500, Jonathan M Davis wrote:
> > On Friday, March 09, 2012 16:48:33 Magnus Lie Hetland wrote:
> > > On 2012-03-09 15:08:42 +0000, bearophile said:
> > > > Magnus Lie Hetland:
> > > >> It seems that File has no method for reading the entire file contents into a string, so I'd have to read and concatenate lines or chunks or something?
> > > > 
> > > > There are std.file.read() and std.file.readText().
> > > 
> > > Yeah, I found those. I guess my post was a bit verbose, but the main
> > > point was that I have a File object, but no file name (because I'm
> > > using std.stdio.tmpfile() in a unit test), so std.file.read() and
> > > std.file.readText() are useless to me... :)
> > 
> > File has a name property. You can do something like
> > 
> > auto file = File.tmpfile();
> > auto filename = file.name;
> > auto str = readText(filename);
> > 
> > I do grant you though that it's a bit odd to need to get the file name and operate on that rather than operating on the File object. It works though, and is a lot cleaner than reading in the file line-by-line, if you don't actually need to do that.
> 
> [...]
> 
> This seems like a strange limitation. Shouldn't it be possible to slurp the entire contents of an already-open file into a string? Perhaps a new method in File?
> 
> Also, using file.name is prone to race conditions in certain situations. (Not that it'd be a problem usually, but just sayin'.)

Of course it's possible to read in the open file into a string. It's just that the only function in Phobos for doing that is in std.file and does not operate on a File. All of the File functions read in only a portion of the file. So, either a new function would have to be added to File, or you'd have to write one yourself (which wouldn't be all that hard using what's already there).

- Jonathan M Davis
March 10, 2012
On 2012-03-09 18:42:01 +0000, Jonathan M Davis said:

> File has a name property. You can do something like
> 
> auto file = File.tmpfile();
> auto filename = file.name;
> auto str = readText(filename);

Yeah -- again, sorry my original post was so verbose, but part of the "problem spec" was that my tempfiles don't seem to have names (i.e., they are unnamed tempfiles, and file.name is null; platform-dependent, I think).

Otherwise, this wouldn't have been a problem :)

-- 
Magnus Lie Hetland
http://hetland.org

March 10, 2012
On Saturday, March 10, 2012 15:44:26 Magnus Lie Hetland wrote:
> On 2012-03-09 18:42:01 +0000, Jonathan M Davis said:
> > File has a name property. You can do something like
> > 
> > auto file = File.tmpfile();
> > auto filename = file.name;
> > auto str = readText(filename);
> 
> Yeah -- again, sorry my original post was so verbose, but part of the "problem spec" was that my tempfiles don't seem to have names (i.e., they are unnamed tempfiles, and file.name is null; platform-dependent, I think).
> 
> Otherwise, this wouldn't have been a problem :)

Then you'll probably have to write a wrapper function which just uses byLine and join to grab the string line by line and then put it back together again. As annoying as it may be, it wouldn't be hard.

- Jonathan M Davis
March 11, 2012
On 2012-03-10 17:10:52 +0000, Jonathan M Davis said:

>> Otherwise, this wouldn't have been a problem :)
> 
> Then you'll probably have to write a wrapper function which just uses byLine
> and join to grab the string line by line and then put it back together again.

Indeed. Not a problem.

Just surprised me that there wasn't a standard way of writing file-related unit tests :)

-- 
Magnus Lie Hetland
http://hetland.org

March 11, 2012
On Sunday, March 11, 2012 13:33:34 Magnus Lie Hetland wrote:
> On 2012-03-10 17:10:52 +0000, Jonathan M Davis said:
> >> Otherwise, this wouldn't have been a problem :)
> > 
> > Then you'll probably have to write a wrapper function which just uses byLine and join to grab the string line by line and then put it back together again.
> Indeed. Not a problem.
> 
> Just surprised me that there wasn't a standard way of writing file-related unit tests :)

Well, most of the file-related unit tests in Phobos don't care much about the contents of the file, and if they do, it's becaus they're testing one of the functions for reading one (such as byLine or read), in which case, they're not looking to read in the whole file at once. So, as far as Phobos' unit tests are concerned, there's not really any need for what you're trying to do. That doesn't mean that it shouldn't be supported, but it just doesn't appear to have ever come up.

- Jonathan M Davis
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home