1/* 2 * Copyright 2008 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.mockftpserver.fake.filesystem 17 18import org.slf4j.Logger; 19import org.slf4j.LoggerFactory; 20import org.mockftpserver.core.util.IoUtil 21 22/** 23 * Tests for FileEntry 24 * 25 * @version $Revision$ - $Date$ 26 * 27 * @author Chris Mair 28 */ 29public class FileEntryTest extends AbstractFileSystemEntryTestCase { 30 31 private static final LOG = LoggerFactory.getLogger(FileEntryTest) 32 private static final CONTENTS = "abc 123 %^& xxx" 33 34 private FileEntry entry 35 36 void testConstructorWithStringContents() { 37 entry = new FileEntry(PATH, CONTENTS) 38 verifyContents(CONTENTS) 39 } 40 41 void testSettingContentsFromString() { 42 entry.setContents(CONTENTS) 43 verifyContents(CONTENTS) 44 } 45 46 void testSettingContentsFromBytes() { 47 byte[] contents = CONTENTS.getBytes() 48 entry.setContents(contents) 49 // Now corrupt the original byte array to make sure the file entry is not affected 50 contents[1] = (byte) '#' 51 verifyContents(CONTENTS) 52 } 53 54 void testSetContents_BytesNotInCharSet() { 55 byte[] contents = [65, -99, 91, -115] as byte[] 56 entry.setContents(contents) 57 verifyContents(contents) 58 } 59 60 void testSetContents_NullString() { 61 entry.setContents((String) null) 62 assert entry.size == 0 63 } 64 65 void testSetContents_NullBytes() { 66 entry.setContents((byte[]) null) 67 assert entry.size == 0 68 } 69 70 void testCreateOutputStream() { 71 // New, empty file 72 OutputStream out = entry.createOutputStream(false) 73 out.write(CONTENTS.getBytes()) 74 verifyContents(CONTENTS) 75 76 // Another OutputStream, append=false 77 out = entry.createOutputStream(false) 78 out.write(CONTENTS.getBytes()) 79 verifyContents(CONTENTS) 80 81 // Another OutputStream, append=true 82 out = entry.createOutputStream(true) 83 out.write(CONTENTS.getBytes()) 84 verifyContents(CONTENTS + CONTENTS) 85 86 // Set contents directly 87 final String NEW_CONTENTS = ",./'\t\r[]-\n=" 88 entry.setContents(NEW_CONTENTS) 89 verifyContents(NEW_CONTENTS) 90 91 // New OutputStream, append=true (so should append to contents we set directly) 92 out = entry.createOutputStream(true) 93 out.write(CONTENTS.getBytes()) 94 verifyContents(NEW_CONTENTS + CONTENTS) 95 96 // Yet another OutputStream, append=true (so should append to accumulated contents) 97 OutputStream out2 = entry.createOutputStream(true) 98 out2.write(CONTENTS.getBytes()) 99 out2.close() // should have no effect 100 verifyContents(NEW_CONTENTS + CONTENTS + CONTENTS) 101 102 // Write with the previous OutputStream (simulate 2 OututStreams writing "concurrently") 103 out.write(NEW_CONTENTS.getBytes()) 104 verifyContents(NEW_CONTENTS + CONTENTS + CONTENTS + NEW_CONTENTS) 105 } 106 107 void testCreateInputStream_NullContents() { 108 verifyContents("") 109 } 110 111 void testCloneWithNewPath() { 112 entry.lastModified = LAST_MODIFIED 113 entry.owner = USER 114 entry.group = GROUP 115 entry.permissions = PERMISSIONS 116 entry.setContents('abc') 117 def clone = entry.cloneWithNewPath(NEW_PATH) 118 119 assert !clone.is(entry) 120 assert clone.path == NEW_PATH 121 assert clone.lastModified == LAST_MODIFIED 122 assert clone.owner == USER 123 assert clone.group == GROUP 124 assert clone.permissions == PERMISSIONS 125 assert clone.createInputStream().text == 'abc' 126 assert !clone.directory 127 } 128 129 void testCloneWithNewPath_WriteToOutputStream() { 130 def outputStream = entry.createOutputStream(false) 131 outputStream.withWriter { writer -> writer.write('ABCDEF') } 132 def clone = entry.cloneWithNewPath(NEW_PATH) 133 134 assert !clone.is(entry) 135 assert clone.path == NEW_PATH 136 assert clone.createInputStream().text == 'ABCDEF' 137 assert !clone.directory 138 } 139 140// void testEquals() { 141// assert entry.equals(entry) 142// assert entry.equals(new FileEntry(path:PATH, lastModified:LAST_MODIFIED)) 143// assert entry.equals(new FileEntry(path:PATH, lastModified:new Date())) // lastModified ignored 144// 145// assert !entry.equals(new FileEntry("xyz", lastModified:LAST_MODIFIED)) 146// assert !entry.equals(new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED)) 147// assert !entry.equals("ABC") 148// assert !entry.equals(null) 149// } 150// 151// void testHashCode() { 152// assert entry.hashCode() == entry.hashCode() 153// assert entry.hashCode() == new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED).hashCode() 154// assert entry.hashCode() == new FileEntry(path:PATH, contents:'abc', new Date()).hashCode() // lastModified ignored 155// 156// assert entry.hashCode() != new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED).hashCode() 157// assert entry.hashCode() != new FileEntry(path:PATH, contents:'abcdef', lastModified:LAST_MODIFIED).hashCode() 158// 159// assert entry.hashCode() == new DirectoryEntry(path:PATH, lastModified:LAST_MODIFIED).hashCode() 160// } 161 162 //------------------------------------------------------------------------- 163 // Implementation of Required Abstract Methods 164 //------------------------------------------------------------------------- 165 166 /** 167 * @see org.mockftpserver.fake.filesystem.AbstractFileSystemEntryTestCase#getImplementationClass() 168 */ 169 protected Class getImplementationClass() { 170 return FileEntry.class 171 } 172 173 /** 174 * @see org.mockftpserver.fake.filesystem.AbstractFileSystemEntryTestCase#isDirectory() 175 */ 176 protected boolean isDirectory() { 177 return false 178 } 179 180 //------------------------------------------------------------------------- 181 // Test setup 182 //------------------------------------------------------------------------- 183 184 void setUp() { 185 super.setUp() 186 entry = new FileEntry(PATH) 187 } 188 189 //------------------------------------------------------------------------- 190 // Internal Helper Methods 191 //------------------------------------------------------------------------- 192 193 /** 194 * Verify the expected contents of the file entry, read from its InputSteam 195 * @param expectedContents - the expected contents, as a String 196 * @throws IOException 197 */ 198 private void verifyContents(String expectedContents) { 199 LOG.info("expectedContents=$expectedContents") 200 verifyContents(expectedContents.bytes) 201 } 202 203 /** 204 * Verify the expected contents of the file entry, read from its InputSteam 205 * @param expectedContents - the expected contents, as a byte[] 206 * @throws IOException 207 */ 208 private void verifyContents(byte[] expectedContents) { 209 byte[] bytes = IoUtil.readBytes(entry.createInputStream()) 210 def bytesAsList = bytes as List 211 LOG.info("bytes=$bytesAsList") 212 assert bytes == expectedContents, "actual=$bytesAsList expected=${expectedContents as byte[]}" 213 assert entry.getSize() == expectedContents.length 214 } 215 216} 217