Use a logger or roll my own?

  • (2 Pages)
  • +
  • 1
  • 2

27 Replies - 973 Views - Last Post: 17 June 2013 - 02:48 AM Rate Topic: -----

#16 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2684
  • View blog
  • Posts: 11,337
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 02:07 PM

Well as you said earlier, why can't you use a StringWriter and hold everything in memory?
Was This Post Helpful? 1
  • +
  • -

#17 CasiOo  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1390
  • View blog
  • Posts: 3,076
  • Joined: 05-April 11

Re: Use a logger or roll my own?

Posted 15 June 2013 - 02:29 PM

Can't you just check the size of the file before and after?
Well, it still requires some IO behind the scenes
Please notice the extra characters added to the file if you are using functions like println
		final String outputText = "xxx";
		File file = new File("Test.tmp");
		file.deleteOnExit();
		
		try (PrintWriter out = new PrintWriter(file, "UTF-8")) {
			out.print(outputText);
		}
		
		System.out.println("File size matches expected size: " + (outputText.getBytes("UTF-8").length == file.length()));



I don't like that you are actually writing to the file system in your tests. Would it be possible to pass around a stream instead?
I haven't been able to figure out a good way of doing the above yet ^^

But yeah, checking the size of the file doesn't really help if you also need to check the content of it. Would still be better if you could access the stream, maybe you would have to extend the class under test and add some methods created just for unit testing

This post has been edited by CasiOo: 15 June 2013 - 02:31 PM

Was This Post Helpful? 1
  • +
  • -

#18 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2684
  • View blog
  • Posts: 11,337
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 15 June 2013 - 02:34 PM

Quote

try (PrintWriter out = new PrintWriter(file, "UTF-8")) 

could of course be
try (Writer out = new StringWriter() 

This post has been edited by g00se: 15 June 2013 - 02:35 PM

Was This Post Helpful? 1
  • +
  • -

#19 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1949
  • View blog
  • Posts: 4,048
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 04:21 PM

Quote

Can't you just check the size of the file before and after?
Well, it still requires some IO behind the scenes


I could but file is tiny. I'm not worried about execution time. It's just accessing the file system in tests I don't like. I actually think checking the file size would be trickier to make it cross platform. See below.

Quote

Please notice the extra characters added to the file if you are using functions like println


Absolutely. PrintWriter.println() uses the platform specific newline. I account for this by using String.format() with %n for newlines (i.e. "xxx%nyyy%naaa%nbbb%nccc%n"). This appears to give the correct like endings, at least in Windows. If it works on Windows, I'm confident it will produce a simple \n on linux.

Quote

Would it be possible to pass around a stream instead?


In the guts of it is a FileWriter whose constructor takes a boolean. True to append, false to overwrite. Behind the scenes, I assume it delegates to a FileOutputStream whose constructor also has that boolean flag. As far as I can tell, no other streams have that flag.

I think I'm stuck with accessing the file system. Thanks for the suggestions anyway!
Was This Post Helpful? 0
  • +
  • -

#20 CasiOo  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1390
  • View blog
  • Posts: 3,076
  • Joined: 05-April 11

Re: Use a logger or roll my own?

Posted 15 June 2013 - 04:45 PM

Yes accessing the file system seems like the easiest and quickest solution
Are you doing test driven development? Sometimes it just isn't worth the time writing the test when writing the test takes at minimum 5x the time it takes to write the class :D

I see you are using java 1.7, so no reason to not use the API methods
public void testAppendToFile() throws IOException {
	List<String> testData = new ArrayList<String>();
	testData.add("xxx");
	
	//Do the actual operation
	
	List<String> testResults = Files.readAllLines(filePath, StandardCharsets.UTF_8);
	
	assertTrue(testData.equals(testResults));
}


Was This Post Helpful? 1
  • +
  • -

#21 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1949
  • View blog
  • Posts: 4,048
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 15 June 2013 - 05:17 PM

I swear I keep forgetting about the new IO classes in Java 7. Thanks!

Quote

Are you doing test driven development? Sometimes it just isn't worth the time writing the test when writing the test takes at minimum 5x the time it takes to write the class


Yes, TDD but not so dogmatically that I'm spending all my time on tests. Coverage is 85%. Most of what isn't covered is lines that deal with exceptions from API calls. I could go through some contortions to cover them but there lies the path to madness. The test we are talking about actually didn't take a lot of time to write and it's an important one. If I get the code wrong, it could be destructive in that user's files might get overwritten.
Was This Post Helpful? 0
  • +
  • -

#22 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2684
  • View blog
  • Posts: 11,337
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 16 June 2013 - 03:46 AM

I'm still confused as to why this is not doable in memory
Was This Post Helpful? 0
  • +
  • -

#23 CasiOo  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1390
  • View blog
  • Posts: 3,076
  • Joined: 05-April 11

Re: Use a logger or roll my own?

Posted 16 June 2013 - 05:47 AM

View Postg00se, on 16 June 2013 - 10:46 AM, said:

I'm still confused as to why this is not doable in memory


Feel free to show an example
It should be able to test for appending and the added content to the file
I guess the IO should all happen in the RecordCommandsToWriter class, maybe passing a writer as argument would be doable, but then the test problem just transfers to another class =o?
Was This Post Helpful? 0
  • +
  • -

#24 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2684
  • View blog
  • Posts: 11,337
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 16 June 2013 - 06:13 AM

I'll try, but i'm not quite sure what the operation is. Is it just a question of substringing?
Was This Post Helpful? 0
  • +
  • -

#25 CasiOo  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 1390
  • View blog
  • Posts: 3,076
  • Joined: 05-April 11

Re: Use a logger or roll my own?

Posted 16 June 2013 - 07:50 AM

View Postg00se, on 16 June 2013 - 01:13 PM, said:

I'll try, but i'm not quite sure what the operation is. Is it just a question of substringing?

I believe the record method is just appending a line to the existing file
If that's what you are asking ^^
Was This Post Helpful? 0
  • +
  • -

#26 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2684
  • View blog
  • Posts: 11,337
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 16 June 2013 - 10:20 AM

Quote

I believe the record method is just appending a line to the existing file
If that's what you are asking
Well i wasn't really ;) But the in-memory equivalent of that would be to append to an Appendable of course. I was really talking about what appeared to be a substring/subset algo
Was This Post Helpful? 0
  • +
  • -

#27 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1949
  • View blog
  • Posts: 4,048
  • Joined: 11-December 07

Re: Use a logger or roll my own?

Posted 16 June 2013 - 11:07 AM

Substring really isn't anything to do with it. Here is a simple JUnit test case. One test uses a correctly configured FileWriter. It passes. The second test simulates what happens if I configure the FileWriter incorrectly. It fails which highlights the incorrect configuration.

The third test uses a StringWriter. It passes. If you can make this fail by changing the configuration then I can do it in memory. However, I don't think it has the concept of append/overwrite.

import static org.junit.Assert.*;

import java.io.*;
import java.util.*;

import org.junit.*;

public class AppendTest {

	@Test
	public void testAppend_OK() throws IOException {
		File f = prepareFile();
		try (Writer out = new FileWriter(f, true)) {
			out.write("Appended text.");
		}
		assertCorrectContents(fileContents(f));
	}

	private File prepareFile() throws IOException {
		File f = File.createTempFile("junit - temp file", ".tmp");
		f.deleteOnExit();
		try (PrintWriter out = new PrintWriter(f)) {
			out.write("Initial contents. ");
		}
		return f;
	}

	private void assertCorrectContents(String actual) {
		String expected = "Initial contents. Appended text.";
		assertEquals(expected, actual);
	}

	private String fileContents(File f) throws FileNotFoundException {
		try (Scanner in = new Scanner(f)) {
			in.useDelimiter("\\z");
			return in.next();
		}
	}

	@Test
	public void testAppend_IncorrectlyConfigured() throws IOException {
		File f = prepareFile();
		try (Writer out = new FileWriter(f, false)) {
			out.write("Appended text.");
		}
		assertCorrectContents(fileContents(f));
	}

	@Test
	public void testAppend_InMemory() throws IOException {
		StringWriter inMemoryWriter = new StringWriter();
		inMemoryWriter.write("Initial contents. ");
		try (Writer out = inMemoryWriter) {
			out.write("Appended text.");
			out.flush();
		}
		assertCorrectContents(inMemoryWriter.toString());
	}

}


Was This Post Helpful? 0
  • +
  • -

#28 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2684
  • View blog
  • Posts: 11,337
  • Joined: 20-September 08

Re: Use a logger or roll my own?

Posted 17 June 2013 - 02:48 AM

But first, testAppend_IncorrectlyConfigured(), without parameterization, doesn't make sense really. The outcome is determined as you know the file has not been opened in append mode ..

Quote

Substring really isn't anything to do with it.

It would seem to me to be central to the issue, being definitive in determining whether an append has occurred, which could be defined thus:

    public static boolean wasAppended(CharSequence appendedCandidate,
        CharSequence original) {
        // Does what was appended to contain a substring of the original at position 0 and
        // is it longer than the original?
        return (appendedCandidate.length() > original.length()) &&
        appendedCandidate.subSequence(0, original.length()).equals(original);
    }

This post has been edited by g00se: 17 June 2013 - 03:06 AM
Reason for edit:: Clarification

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2