FileEntryTest.groovy revision a5c19061b721f203631e1969bf38127301e29414
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.apache.log4j.Logger
19import org.mockftpserver.core.util.IoUtil
20
21/**
22 * Tests for FileEntry
23 *
24 * @version $Revision$ - $Date$
25 *
26 * @author Chris Mair
27 */
28public class FileEntryTest extends AbstractFileSystemEntryTest {
29
30    private static final LOG = Logger.getLogger(FileEntryTest)
31    private static final CONTENTS = "abc 123 %^& xxx"
32
33    private FileEntry entry
34
35    void testConstructorWithStringContents() {
36        entry = new FileEntry(PATH, CONTENTS)
37        verifyContents(CONTENTS)
38    }
39
40    void testSettingContentsFromString() {
41        entry.setContents(CONTENTS)
42        verifyContents(CONTENTS)
43    }
44
45    void testSettingContentsFromBytes() {
46        byte[] contents = CONTENTS.getBytes()
47        entry.setContents(contents)
48        // Now corrupt the original byte array to make sure the file entry is not affected
49        contents[1] = (byte) '#'
50        verifyContents(CONTENTS)
51    }
52
53    void testSetContents_NullString() {
54        entry.setContents((String) null)
55        assert entry.size == 0
56    }
57
58    void testSetContents_NullBytes() {
59        entry.setContents((byte[]) null)
60        assert entry.size == 0
61    }
62
63    void testCreateOutputStream() {
64        // New, empty file
65        OutputStream out = entry.createOutputStream(false)
66        out.write(CONTENTS.getBytes())
67        verifyContents(CONTENTS)
68
69        // Another OutputStream, append=false
70        out = entry.createOutputStream(false)
71        out.write(CONTENTS.getBytes())
72        verifyContents(CONTENTS)
73
74        // Another OutputStream, append=true
75        out = entry.createOutputStream(true)
76        out.write(CONTENTS.getBytes())
77        verifyContents(CONTENTS + CONTENTS)
78
79        // Set contents directly
80        final String NEW_CONTENTS = ",./'\t\r[]-\n="
81        entry.setContents(NEW_CONTENTS)
82        verifyContents(NEW_CONTENTS)
83
84        // New OutputStream, append=true (so should append to contents we set directly)
85        out = entry.createOutputStream(true)
86        out.write(CONTENTS.getBytes())
87        verifyContents(NEW_CONTENTS + CONTENTS)
88
89        // Yet another OutputStream, append=true (so should append to accumulated contents)
90        OutputStream out2 = entry.createOutputStream(true)
91        out2.write(CONTENTS.getBytes())
92        out2.close()       // should have no effect
93        verifyContents(NEW_CONTENTS + CONTENTS + CONTENTS)
94
95        // Write with the previous OutputStream (simulate 2 OututStreams writing "concurrently")
96        out.write(NEW_CONTENTS.getBytes())
97        verifyContents(NEW_CONTENTS + CONTENTS + CONTENTS + NEW_CONTENTS)
98    }
99
100    void testCreateInputStream_NullContents() {
101        verifyContents("")
102    }
103
104    void testCloneWithNewPath() {
105        entry.lastModified = LAST_MODIFIED
106        entry.owner = USER
107        entry.group = GROUP
108        entry.permissions = PERMISSIONS
109        entry.setContents('abc')
110        def clone = entry.cloneWithNewPath(NEW_PATH)
111
112        assert !clone.is(entry)
113        assert clone.path == NEW_PATH
114        assert clone.lastModified == LAST_MODIFIED
115        assert clone.owner == USER
116        assert clone.group == GROUP
117        assert clone.permissions == PERMISSIONS
118        assert clone.createInputStream().text == 'abc'
119        assert !clone.directory
120    }
121
122    void testCloneWithNewPath_WriteToOutputStream() {
123        def outputStream = entry.createOutputStream(false)
124        outputStream.withWriter { writer -> writer.write('ABCDEF') }
125        def clone = entry.cloneWithNewPath(NEW_PATH)
126
127        assert !clone.is(entry)
128        assert clone.path == NEW_PATH
129        assert clone.createInputStream().text == 'ABCDEF'
130        assert !clone.directory
131    }
132
133//    void testEquals() {
134//        assert entry.equals(entry)
135//        assert entry.equals(new FileEntry(path:PATH, lastModified:LAST_MODIFIED))
136//        assert entry.equals(new FileEntry(path:PATH, lastModified:new Date())) // lastModified ignored
137//
138//        assert !entry.equals(new FileEntry("xyz", lastModified:LAST_MODIFIED))
139//        assert !entry.equals(new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED))
140//        assert !entry.equals("ABC")
141//        assert !entry.equals(null)
142//    }
143//
144//    void testHashCode() {
145//        assert entry.hashCode() == entry.hashCode()
146//        assert entry.hashCode() == new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED).hashCode()
147//        assert entry.hashCode() == new FileEntry(path:PATH, contents:'abc', new Date()).hashCode()  // lastModified ignored
148//
149//        assert entry.hashCode() != new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED).hashCode()
150//        assert entry.hashCode() != new FileEntry(path:PATH, contents:'abcdef', lastModified:LAST_MODIFIED).hashCode()
151//
152//        assert entry.hashCode() == new DirectoryEntry(path:PATH, lastModified:LAST_MODIFIED).hashCode()
153//    }
154
155    //-------------------------------------------------------------------------
156    // Implementation of Required Abstract Methods
157    //-------------------------------------------------------------------------
158
159    /**
160     * @see org.mockftpserver.fake.filesystem.AbstractFileSystemEntryTest#getImplementationClass()
161     */
162    protected Class getImplementationClass() {
163        return FileEntry.class
164    }
165
166    /**
167     * @see org.mockftpserver.fake.filesystem.AbstractFileSystemEntryTest#isDirectory()
168     */
169    protected boolean isDirectory() {
170        return false
171    }
172
173    //-------------------------------------------------------------------------
174    // Test setup
175    //-------------------------------------------------------------------------
176
177    /**
178     * @see org.mockftpserver.test.AbstractTest#setUp()
179     */
180    void setUp() {
181        super.setUp()
182        entry = new FileEntry(PATH)
183    }
184
185    //-------------------------------------------------------------------------
186    // Internal Helper Methods
187    //-------------------------------------------------------------------------
188
189    /**
190     * Verify the expected contents of the file entry, read from its InputSteam
191     * @param expectedContents - the expected contents
192     * @throws IOException
193     */
194    private void verifyContents(String expectedContents) {
195        byte[] bytes = IoUtil.readBytes(entry.createInputStream())
196        LOG.info("bytes=[" + new String(bytes) + "]")
197        assertEquals("contents: actual=[" + new String(bytes) + "]", expectedContents.getBytes(), bytes)
198        assert entry.getSize() == expectedContents.length()
199    }
200
201}
202