/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed 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 jetbrains.buildServer.tools.test;
import jetbrains.buildServer.tools.*;
import jetbrains.buildServer.tools.rules.PathRule;
import jetbrains.buildServer.tools.rules.PathSettings;
import jetbrains.buildServer.tools.rules.RulesParser;
import jetbrains.buildServer.tools.rules.VersionRule;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jmock.Mockery;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author Eugene Petrenko (eugene.petrenko@gmail.com)
* Date: 11.11.11 15:29
*/
public class RulesBaseTestCase extends BaseTestCase {
protected Mockery m;
protected Continuation c;
protected File myHome;
protected ErrorReporting rep;
@BeforeMethod
@Override
public void setUp() throws IOException {
super.setUp();
myHome = createTempDir();
m = new Mockery();
c = m.mock(Continuation.class);
rep = m.mock(ErrorReporting.class);
}
@AfterMethod
@Override
public void tearDown() {
super.tearDown();
m.assertIsSatisfied();
}
@NotNull
protected PathSettings parseConfig(@NotNull final String configText) throws IOException {
return new RulesParser().parseConfig(new StringReader(configText)).build();
}
@NotNull
public ScanFile mockFile(@NotNull final String relPath) {
return new ScanFile() {
@NotNull
public InputStream openStream() throws IOException {
throw new UnsupportedOperationException();
}
@NotNull
public String getName() {
return relPath;
}
public boolean isFile() {
return false;
}
};
}
@NotNull
public ScanFile mockFile(@NotNull final String relPath, @NotNull final byte[] content) {
return new ScanFile() {
@NotNull
public InputStream openStream() throws IOException {
return new ByteArrayInputStream(content);
}
@NotNull
public String getName() {
return relPath;
}
public boolean isFile() {
return true;
}
};
}
protected class Expectations extends org.jmock.Expectations {
protected BaseMatcher<ScanFile> file(@NotNull final String path) {
final String name = resolve(path);
return new BaseMatcher<ScanFile>() {
public boolean matches(Object item) {
ScanFile sf = (ScanFile) item;
return sf.getName().equals(name);
}
public void describeTo(Description description) {
description.appendText("ScanFile{" + name + "}");
}
};
}
@NotNull
private String resolve(@NotNull String path) {
return mockFile(path).getName();
}
protected BaseMatcher<VersionRule> versionRule(@NotNull final String path) {
final String name = resolve(path);
return new BaseMatcher<VersionRule>() {
public boolean matches(Object item) {
VersionRule vs = (VersionRule) item;
return vs.getPath().equals(name);
}
public void describeTo(Description description) {
description.appendText("Version Rule: " + name);
}
};
}
}
public void expectFile(@NotNull final String name) {
m.checking(new Expectations(){{
oneOf(c).postTask(with(file(name)));
}});
}
public void expectCheckError(@NotNull final String name, @NotNull final ErrorKind kind) {
m.checking(new Expectations(){{
oneOf(rep).postCheckError(with(file(name)), with(equal(kind)), with(any(String.class)));
}});
}
public void expectGenericError(@NotNull final String name) {
m.checking(new Expectations(){{
oneOf(rep).postError(with(file(name)), with(any(String.class)));
}});
}
public void expectRuleNotVisited(@NotNull final String name) {
m.checking(new Expectations(){{
oneOf(rep).ruleNotVisited(with(versionRule(name)));
}});
}
@NotNull
protected byte[] zipStream(@NotNull final String... files) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
zipStream(os, files);
os.close();
return os.toByteArray();
}
@NotNull
protected ZipAction zipStream(@NotNull final String name, @NotNull final ZipAction... files) throws IOException {
final byte[] bytes = zipStream(files);
return new ZipAction(name) {
@Override
public byte[] getContent() {
return bytes;
}
};
}
@NotNull
protected ZipAction file(@NotNull final String name, @NotNull final byte[] content) {
return new ZipFileAction(name, content);
}
protected byte[] zipStream(@NotNull final ZipAction... files) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
zipStream(os, files);
os.close();
return os.toByteArray();
}
private void zipStream(@NotNull final OutputStream os, @NotNull final String[] files) throws IOException {
final ZipOutputStream zos = new ZipOutputStream(os);
for (String file : files) {
if (!file.contains(".")) {
zos.putNextEntry(new ZipEntry(file));
} else {
int sp = file.indexOf('!');
if (sp < 0) {
zos.putNextEntry(new ZipEntry(file));
zos.write(file.getBytes());
} else {
final String path = file.substring(0, sp);
zos.putNextEntry(new ZipEntry(path));
final String[] rest = file.substring(sp).split(",");
zipStream(zos, rest);
}
}
}
zos.finish();
}
private void zipStream(@NotNull final OutputStream os, @NotNull final ZipAction[] files) throws IOException {
final ZipOutputStream zos = new ZipOutputStream(os);
for (ZipAction file : files) {
zos.putNextEntry(new ZipEntry(file.getName()));
final byte[] content = file.getContent();
if (content != null) {
zos.write(content);
}
}
zos.finish();
}
protected abstract class ZipAction {
private final String myName;
public ZipAction(@NotNull final String name) {
myName = name;
}
public String getName() {
return myName;
}
@Nullable
public abstract byte[] getContent();
}
protected class ZipFileAction extends ZipAction {
@NotNull
private final byte[] myContent;
public ZipFileAction(@NotNull String name, @NotNull final byte[] content) {
super(name);
myContent = content;
}
@NotNull
@Override
public byte[] getContent() {
return myContent;
}
}
protected void saveFile(@NotNull final String name, @NotNull final byte[] ps) throws IOException {
final File file = new File(myHome, name);
//noinspection ResultOfMethodCallIgnored
file.getParentFile().mkdirs();
OutputStream os = new FileOutputStream(file);
os.write(ps);
os.close();
}
@NotNull
protected byte[] classBytes(int version) {
return new byte[]{(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE, 0, 0, 0, (byte) version, 0, 0, 0, 0, 0};
}
@NotNull
protected ZipAction classBytes(@NotNull String name, int version) {
return file(name, classBytes(version));
}
protected void assertRule(@Nullable final PathRule actual, @Nullable final String expectedPath) {
if (actual == null) {
Assert.assertNull(expectedPath);
} else {
Assert.assertEquals(actual.getPath(), expectedPath);
}
}
}