blob: 8ad1cf8b527c1eed4fd81cea5d22d34d633b2163 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package gdk
import groovy.io.FileType
import groovy.io.FileVisitResult
import groovy.test.GroovyTestCase
import groovy.transform.CompileStatic
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import static org.junit.Assume.assumeTrue
@RunWith(JUnit4)
class WorkingWithIOSpecTest extends GroovyTestCase {
private final static boolean unixlike =
System.getProperty('os.name').contains('Linux') ||
System.getProperty('os.name').contains('Mac OS')
private final static boolean windoz =
System.getProperty('os.name').contains('Windows')
private assumeUnixLikeSystem() {
assumeTrue('Test requires unix like system.', unixlike)
}
@CompileStatic
private void doInTmpDir(Closure cl) {
def baseDir = File.createTempDir()
try {
cl.call(new FileTreeBuilder(baseDir))
} finally {
baseDir.deleteDir()
}
}
@Test
void testFileIntro() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
dir.'haiku.txt'('''Un vieil étang et
Une grenouille qui plonge,
Le bruit de l'eau.''')
// tag::print_file_lines[]
new File(baseDir, 'haiku.txt').eachLine { line ->
println line
}
// end::print_file_lines[]
// tag::print_file_lines2[]
new File(baseDir, 'haiku.txt').eachLine { line, nb ->
println "Line $nb: $line"
}
// end::print_file_lines2[]
// tag::collect_lines[]
def list = new File(baseDir, 'haiku.txt').collect {it}
// end::collect_lines[]
// tag::lines_as_strings[]
def array = new File(baseDir, 'haiku.txt') as String[]
// end::lines_as_strings[]
assert list.size()==3
assert array.length==3
def file = new File(baseDir, 'haiku.txt')
// tag::file_bytes[]
byte[] contents = file.bytes
// end::file_bytes[]
}
}
@Test
void testWithReader() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
dir.'haiku.txt'('''Un vieil étang et
Une grenouille qui plonge,
Le bruit de l'eau.
Fin.''')
try {
// tag::withreader_exception[]
def count = 0, MAXSIZE = 3
new File(baseDir,"haiku.txt").withReader { reader ->
while (reader.readLine()) {
if (++count > MAXSIZE) {
throw new RuntimeException('Haiku should only have 3 verses')
}
}
}
// end::withreader_exception[]
assert false
} catch (RuntimeException e) {
assert e.message == 'Haiku should only have 3 verses'
}
}
}
@Test
void testWithWriter() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
// tag::withwriter_example[]
new File(baseDir,'haiku.txt').withWriter('utf-8') { writer ->
writer.writeLine 'Into the ancient pond'
writer.writeLine 'A frog jumps'
writer.writeLine 'Water’s sound!'
}
// end::withwriter_example[]
}
}
@Test
void testLeftShift() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
// tag::file_leftshift[]
new File(baseDir,'haiku.txt') << '''Into the ancient pond
A frog jumps
Water’s sound!'''
// end::file_leftshift[]
}
}
@Test
void testSetBytes() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
def file = new File(baseDir, 'binary.bin')
// tag::file_setbytes[]
file.bytes = [66,22,11]
// end::file_setbytes[]
}
}
@Test
void testEachFile() {
doInTmpDir { builder ->
File dir = builder {
'file1.txt'('file 1')
'file2.txt'('file 2')
'file3.bin'('file 3')
}
// tag::eachfile[]
dir.eachFile { file -> // <1>
println file.name
}
dir.eachFileMatch(~/.*\.txt/) { file -> // <2>
println file.name
}
// end::eachfile[]
}
}
@Test
void testEachFileRecurse() {
doInTmpDir { builder ->
File dir = builder {
'file1.txt'('file 1')
'file2.txt'('file 2')
bin {
'file3.bin'('file 3')
}
}
// tag::eachfilerecurse[]
dir.eachFileRecurse { file -> // <1>
println file.name
}
dir.eachFileRecurse(FileType.FILES) { file -> // <2>
println file.name
}
// end::eachfilerecurse[]
}
}
@Test
void testTraverse() {
doInTmpDir { builder ->
File dir = builder {
'file1.txt'('file 1')
'file2.txt'('file 2')
bin {
'file3.bin'('file 3')
}
}
// tag::traverse[]
dir.traverse { file ->
if (file.directory && file.name=='bin') {
FileVisitResult.TERMINATE // <1>
} else {
println file.name
FileVisitResult.CONTINUE // <2>
}
}
// end::traverse[]
}
}
@Test
void testGetInputStreamFromFile() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
dir.'haiku.txt'('''Un vieil étang et
Une grenouille qui plonge,
Le bruit de l'eau.
Fin.''')
// tag::newinputstream[]
def is = new File(baseDir,'haiku.txt').newInputStream()
// do something ...
is.close()
// end::newinputstream[]
// tag::withinputstream[]
new File(baseDir,'haiku.txt').withInputStream { stream ->
// do something ...
}
// end::withinputstream[]
}
}
@Test
void testFileOutputStream() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
// tag::newoutputstream[]
def os = new File(baseDir,'data.bin').newOutputStream()
// do something ...
os.close()
// end::newoutputstream[]
// tag::withoutputstream[]
new File(baseDir,'data.bin').withOutputStream { stream ->
// do something ...
}
// end::withoutputstream[]
}
}
@Test
void testDataInputOutput() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
def file = new File(baseDir, 'data.bin')
// tag::data_in_out[]
boolean b = true
String message = 'Hello from Groovy'
// Serialize data into a file
file.withDataOutputStream { out ->
out.writeBoolean(b)
out.writeUTF(message)
}
// ...
// Then read it back
file.withDataInputStream { input ->
assert input.readBoolean() == b
assert input.readUTF() == message
}
// end::data_in_out[]
}
}
@Test
void testObjectInputOutput() {
doInTmpDir { dir ->
File baseDir = dir.baseDir
def file = new File(baseDir, 'data.bin')
// tag::object_in_out[]
Person p = new Person(name:'Bob', age:76)
// Serialize data into a file
file.withObjectOutputStream { out ->
out.writeObject(p)
}
// ...
// Then read it back
file.withObjectInputStream { input ->
def p2 = input.readObject()
assert p2.name == p.name
assert p2.age == p.age
}
// end::object_in_out[]
}
}
@Test
void testProcess1() {
if (unixlike) {
// tag::process_list_files[]
def process = "ls -l".execute() // <1>
println "Found text ${process.text}" // <2>
// end::process_list_files[]
assert process instanceof Process
}
if (windoz) {
try {
// tag::dir_windows[]
def process = "dir".execute()
println "${process.text}"
// end::dir_windows[]
// we do not check that the expected exception is really thrown,
// because the command succeeds if PATH contains cygwin
} catch (e) {
// tag::dir_windows_fixed[]
def process = "cmd /c dir".execute()
println "${process.text}"
// end::dir_windows_fixed[]
}
}
}
@Test
void testProcess2() {
assumeUnixLikeSystem()
// tag::process_list_files_line_by_line[]
def process = "ls -l".execute() // <1>
process.in.eachLine { line -> // <2>
println line // <3>
}
// end::process_list_files_line_by_line[]
assert process instanceof Process
}
@Test
void testProcessConsumeOutput() {
assumeUnixLikeSystem()
doInTmpDir { b ->
File file = null
def tmpDir = b.tmp {
file = 'foo.tmp'('foo')
}
assert file.exists()
// tag::consumeoutput[]
def p = "rm -f foo.tmp".execute([], tmpDir)
p.consumeProcessOutput()
p.waitFor()
// end::consumeoutput[]
assert !file.exists()
}
}
@Test
void testProcessPipe() {
assumeUnixLikeSystem()
doInTmpDir { b ->
def proc1, proc2, proc3, proc4
// tag::pipe_example_1[]
proc1 = 'ls'.execute()
proc2 = 'tr -d o'.execute()
proc3 = 'tr -d e'.execute()
proc4 = 'tr -d i'.execute()
proc1 | proc2 | proc3 | proc4
proc4.waitFor()
if (proc4.exitValue()) {
println proc4.err.text
} else {
println proc4.text
}
// end::pipe_example_1[]
// tag::pipe_example_2[]
def sout = new StringBuilder()
def serr = new StringBuilder()
proc2 = 'tr -d o'.execute()
proc3 = 'tr -d e'.execute()
proc4 = 'tr -d i'.execute()
proc4.consumeProcessOutput(sout, serr)
proc2 | proc3 | proc4
[proc2, proc3].each { it.consumeProcessErrorStream(serr) }
proc2.withWriter { writer ->
writer << 'testfile.groovy'
}
proc4.waitForOrKill(1000)
println "Standard output: $sout"
println "Standard error: $serr"
// end::pipe_example_2[]
}
}
public static class Person implements Serializable {
String name
int age
}
}