1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.io.output;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.fail;
21
22 import java.io.IOException;
23 import java.io.StringWriter;
24 import java.nio.charset.Charset;
25 import java.nio.charset.CharsetDecoder;
26 import java.nio.charset.StandardCharsets;
27 import java.nio.file.StandardOpenOption;
28 import java.util.Random;
29
30 import org.apache.commons.io.Charsets;
31 import org.apache.commons.io.charset.CharsetDecoders;
32 import org.junit.jupiter.api.Test;
33
34
35
36
37 public class WriterOutputStreamTest {
38
39 private static final String UTF_16LE = StandardCharsets.UTF_16LE.name();
40 private static final String UTF_16BE = StandardCharsets.UTF_16BE.name();
41 private static final String UTF_16 = StandardCharsets.UTF_16.name();
42 private static final String UTF_8 = StandardCharsets.UTF_8.name();
43 private static final String TEST_STRING = "\u00e0 peine arriv\u00e9s nous entr\u00e2mes dans sa chambre";
44 private static final String LARGE_TEST_STRING;
45
46 static {
47 final StringBuilder buffer = new StringBuilder();
48 for (int i=0; i<100; i++) {
49 buffer.append(TEST_STRING);
50 }
51 LARGE_TEST_STRING = buffer.toString();
52 }
53
54 private final Random random = new Random();
55
56 @Test
57 public void testFlush() throws IOException {
58 final StringWriter writer = new StringWriter();
59 try (WriterOutputStream out = new WriterOutputStream(writer, "us-ascii", 1024, false)) {
60 out.write("abc".getBytes(StandardCharsets.US_ASCII));
61 assertEquals(0, writer.getBuffer().length());
62 out.flush();
63 assertEquals("abc", writer.toString());
64 }
65 }
66
67 @Test
68 public void testLargeUTF8CharsetWithBufferedWrite() throws IOException {
69 testWithBufferedWrite(LARGE_TEST_STRING, UTF_8);
70 }
71
72 @Test
73 public void testLargeUTF8CharsetWithSingleByteWrite() throws IOException {
74 testWithSingleByteWrite(LARGE_TEST_STRING, StandardCharsets.UTF_8);
75 }
76
77 @Test
78 public void testLargeUTF8WithBufferedWrite() throws IOException {
79 testWithBufferedWrite(LARGE_TEST_STRING, UTF_8);
80 }
81
82 @Test
83 public void testLargeUTF8WithSingleByteWrite() throws IOException {
84 testWithSingleByteWrite(LARGE_TEST_STRING, UTF_8);
85 }
86
87 @Test
88 public void testNullCharsetDecoderWithSingleByteWrite() throws IOException {
89 testWithSingleByteWrite(TEST_STRING, (CharsetDecoder) null);
90 }
91
92 @Test
93 public void testNullCharsetNameWithSingleByteWrite() throws IOException {
94 testWithSingleByteWrite(TEST_STRING, (String) null);
95 }
96
97 @Test
98 public void testNullCharsetWithSingleByteWrite() throws IOException {
99 testWithSingleByteWrite(TEST_STRING, (Charset) null);
100 }
101
102 @Test
103 public void testUTF16BEWithBufferedWrite() throws IOException {
104 testWithBufferedWrite(TEST_STRING, UTF_16BE);
105 }
106
107 @Test
108 public void testUTF16BEWithSingleByteWrite() throws IOException {
109 testWithSingleByteWrite(TEST_STRING, UTF_16BE);
110 }
111
112 @Test
113 public void testUTF16LEWithBufferedWrite() throws IOException {
114 testWithBufferedWrite(TEST_STRING, UTF_16LE);
115 }
116
117 @Test
118 public void testUTF16LEWithSingleByteWrite() throws IOException {
119 testWithSingleByteWrite(TEST_STRING, UTF_16LE);
120 }
121
122 @Test
123 public void testUTF16WithBufferedWrite() throws IOException {
124 try {
125 testWithBufferedWrite(TEST_STRING, UTF_16);
126 } catch (final UnsupportedOperationException e) {
127 if (!System.getProperty("java.vendor").contains("IBM")) {
128 fail("This test should only throw UOE on IBM JDKs with broken UTF-16");
129 }
130 }
131 }
132
133 @Test
134 public void testUTF16WithSingleByteWrite() throws IOException {
135 try {
136 testWithSingleByteWrite(TEST_STRING, UTF_16);
137 } catch (final UnsupportedOperationException e){
138 if (!System.getProperty("java.vendor").contains("IBM")){
139 fail("This test should only throw UOE on IBM JDKs with broken UTF-16");
140 }
141 }
142 }
143
144 @Test
145 public void testUTF8WithBufferedWrite() throws IOException {
146 testWithBufferedWrite(TEST_STRING, UTF_8);
147 }
148
149 @Test
150 public void testUTF8WithSingleByteWrite() throws IOException {
151 testWithSingleByteWrite(TEST_STRING, UTF_8);
152 }
153
154 private void testWithBufferedWrite(final String testString, final String charsetName) throws IOException {
155 final byte[] expected = testString.getBytes(charsetName);
156 final StringWriter writer = new StringWriter();
157 try (WriterOutputStream out = WriterOutputStream.builder().setWriter(writer).setCharset(charsetName).get()) {
158 int offset = 0;
159 while (offset < expected.length) {
160 final int length = Math.min(random.nextInt(128), expected.length - offset);
161 out.write(expected, offset, length);
162 offset += length;
163 }
164 }
165 assertEquals(testString, writer.toString());
166 }
167
168 private void testWithSingleByteWrite(final String testString, final Charset charset) throws IOException {
169 final byte[] bytes = testString.getBytes(Charsets.toCharset(charset));
170 StringWriter writer = new StringWriter();
171 try (WriterOutputStream out = new WriterOutputStream(writer, charset)) {
172 writeOneAtATime(bytes, out);
173 }
174 assertEquals(testString, writer.toString());
175
176 writer = new StringWriter();
177 try (WriterOutputStream out = WriterOutputStream.builder().setWriter(writer).setCharset(charset).get()) {
178 writeOneAtATime(bytes, out);
179 }
180 assertEquals(testString, writer.toString());
181 }
182
183 private void testWithSingleByteWrite(final String testString, final CharsetDecoder charsetDecoder) throws IOException {
184 final byte[] bytes = testString.getBytes(CharsetDecoders.toCharsetDecoder(charsetDecoder).charset());
185 StringWriter writer = new StringWriter();
186 try (WriterOutputStream out = new WriterOutputStream(writer, charsetDecoder)) {
187 writeOneAtATime(bytes, out);
188 }
189 assertEquals(testString, writer.toString());
190
191 writer = new StringWriter();
192 try (WriterOutputStream out = WriterOutputStream.builder().setWriter(writer).setCharsetDecoder(charsetDecoder).get()) {
193 writeOneAtATime(bytes, out);
194 }
195 assertEquals(testString, writer.toString());
196 }
197
198 private void testWithSingleByteWrite(final String testString, final String charsetName) throws IOException {
199 final byte[] bytes = testString.getBytes(Charsets.toCharset(charsetName));
200 StringWriter writer = new StringWriter();
201 try (WriterOutputStream out = new WriterOutputStream(writer, charsetName)) {
202 writeOneAtATime(bytes, out);
203 }
204 assertEquals(testString, writer.toString());
205
206 writer = new StringWriter();
207 try (WriterOutputStream out = WriterOutputStream.builder().setWriter(writer).setCharset(charsetName).get()) {
208 writeOneAtATime(bytes, out);
209 }
210 assertEquals(testString, writer.toString());
211 }
212
213 @Test
214 public void testWriteImmediately() throws IOException {
215 final StringWriter writer = new StringWriter();
216 try (WriterOutputStream out = new WriterOutputStream(writer, "us-ascii", 1024, true)) {
217 out.write("abc".getBytes(StandardCharsets.US_ASCII));
218 assertEquals("abc", writer.toString());
219 }
220
221 try (WriterOutputStream out = WriterOutputStream.builder()
222 .setWriter(writer)
223 .setCharset("us-ascii")
224 .setBufferSize(1024)
225 .setWriteImmediately(true)
226 .setOpenOptions(StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE)
227 .get()) {
228
229 out.write("abc".getBytes(StandardCharsets.US_ASCII));
230 assertEquals("abcabc", writer.toString());
231 }
232 }
233
234 private void writeOneAtATime(final byte[] bytes, final WriterOutputStream out) throws IOException {
235 for (final byte b : bytes) {
236 out.write(b);
237 }
238 }
239 }