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 Arrays.equals(clone.bytes, entry.bytes)
119        assert !clone.directory
120    }
121
122//    void testEquals() {
123//        assert entry.equals(entry)
124//        assert entry.equals(new FileEntry(path:PATH, lastModified:LAST_MODIFIED))
125//        assert entry.equals(new FileEntry(path:PATH, lastModified:new Date())) // lastModified ignored
126//
127//        assert !entry.equals(new FileEntry("xyz", lastModified:LAST_MODIFIED))
128//        assert !entry.equals(new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED))
129//        assert !entry.equals("ABC")
130//        assert !entry.equals(null)
131//    }
132//
133//    void testHashCode() {
134//        assert entry.hashCode() == entry.hashCode()
135//        assert entry.hashCode() == new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED).hashCode()
136//        assert entry.hashCode() == new FileEntry(path:PATH, contents:'abc', new Date()).hashCode()  // lastModified ignored
137//
138//        assert entry.hashCode() != new FileEntry(path:PATH, contents:'abc', lastModified:LAST_MODIFIED).hashCode()
139//        assert entry.hashCode() != new FileEntry(path:PATH, contents:'abcdef', lastModified:LAST_MODIFIED).hashCode()
140//
141//        assert entry.hashCode() == new DirectoryEntry(path:PATH, lastModified:LAST_MODIFIED).hashCode()
142//    }
143
144    //-------------------------------------------------------------------------
145    // Implementation of Required Abstract Methods
146    //-------------------------------------------------------------------------
147
148    /**
149     * @see org.mockftpserver.fake.filesystem.AbstractFileSystemEntryTest#getImplementationClass()
150     */
151    protected Class getImplementationClass() {
152        return FileEntry.class
153    }
154
155    /**
156     * @see org.mockftpserver.fake.filesystem.AbstractFileSystemEntryTest#isDirectory()
157     */
158    protected boolean isDirectory() {
159        return false
160    }
161
162    //-------------------------------------------------------------------------
163    // Test setup
164    //-------------------------------------------------------------------------
165
166    /**
167     * @see org.mockftpserver.test.AbstractTest#setUp()
168     */
169    void setUp() {
170        super.setUp()
171        entry = new FileEntry(PATH)
172    }
173
174    //-------------------------------------------------------------------------
175    // Internal Helper Methods
176    //-------------------------------------------------------------------------
177
178    /**
179     * Verify the expected contents of the file entry, read from its InputSteam
180     * @param expectedContents - the expected contents
181     * @throws IOException
182     */
183    private void verifyContents(String expectedContents) {
184        byte[] bytes = IoUtil.readBytes(entry.createInputStream())
185        LOG.info("bytes=[" + new String(bytes) + "]")
186        assertEquals("contents: actual=[" + new String(bytes) + "]", expectedContents.getBytes(), bytes)
187        assert entry.getSize() == expectedContents.length()
188    }
189
190}
191