Skip to content

Commit

Permalink
Added FreshMark to lib, along with infrastructure necessary to test s…
Browse files Browse the repository at this point in the history
…teps entirely within lib.
  • Loading branch information
nedtwigg committed Dec 7, 2016
1 parent 2dc2232 commit a060ee4
Show file tree
Hide file tree
Showing 7 changed files with 312 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2016 DiffPlug
*
* 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 com.diffplug.spotless.markdown;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.logging.Logger;

import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.JarState;
import com.diffplug.spotless.Provisioner;
import com.diffplug.spotless.ThrowingEx.Supplier;

/** A step for [FreshMark](https://github.com/diffplug/freshmark). */
public class FreshMarkStep {
public static final String defaultVersion() {
return DEFAULT_VERSION;
}

private static final String DEFAULT_VERSION = "1.3.1";
private static final String NAME = "freshmark";
private static final String MAVEN_COORDINATE = "com.diffplug.freshmark:freshmark:";
private static final String FORMATTER_CLASS = "com.diffplug.freshmark.FreshMark";
private static final String FORMATTER_METHOD = "compile";

/** Creates a formatter step for the given version and settings file. */
public static FormatterStep create(Supplier<Map<String, ?>> properties, Provisioner provisioner) {
return create(defaultVersion(), properties, provisioner);
}

/** Creates a formatter step for the given version and settings file. */
public static FormatterStep create(String version, Supplier<Map<String, ?>> properties, Provisioner provisioner) {
return FormatterStep.createCloseableLazy(NAME,
() -> new State(new JarState(MAVEN_COORDINATE + version, provisioner), properties.get()),
State::createFormat);
}

private static class State implements Serializable {
private static final long serialVersionUID = 1L;

/** The jar that contains the eclipse formatter. */
final JarState jarState;
final Map<String, ?> properties;

State(JarState jarState, Map<String, ?> properties) {
this.jarState = Objects.requireNonNull(jarState);
this.properties = Objects.requireNonNull(properties);
}

FormatterFunc.Closeable createFormat() throws Exception {
Logger logger = Logger.getLogger(FreshMarkStep.class.getName());
Consumer<String> loggingStream = logger::warning;

URLClassLoader classLoader = jarState.openIsolatedClassLoader();

// instantiate the formatter and get its format method
Class<?> formatterClazz = classLoader.loadClass(FORMATTER_CLASS);
Object formatter = formatterClazz.getConstructor(Map.class, Consumer.class).newInstance(properties, loggingStream);
Method method = formatterClazz.getMethod(FORMATTER_METHOD, String.class);
return FormatterFunc.Closeable.of(classLoader, input -> (String) method.invoke(formatter, input));
}
}
}
1 change: 1 addition & 0 deletions testlib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dependencies {
compile project(':lib')
compile "com.diffplug.durian:durian-core:${VER_DURIAN}"
compile "com.diffplug.durian:durian-io:${VER_DURIAN}"
compile "com.diffplug.durian:durian-testlib:${VER_DURIAN}"
compile "junit:junit:${VER_JUNIT}"
compile "org.assertj:assertj-core:${VER_ASSERTJ}"
compile gradleTestKit()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2016 DiffPlug
*
* 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 com.diffplug.spotless;

import java.util.ArrayList;
import java.util.List;

import com.diffplug.common.base.Box;
import com.diffplug.common.testing.EqualsTester;

public abstract class StepEqualityTester {
protected abstract FormatterStep create();

protected abstract void setupTest(API api);

public interface API {
void assertThis();

void assertThisEqualToThis();

void areDifferentThan();
}

public void testEquals() {
List<List<Object>> allGroups = new ArrayList<>();
Box<List<Object>> currentGroup = Box.of(new ArrayList<>());
API api = new API() {
@Override
public void assertThis() {
currentGroup.get().add(create());
}

@Override
public void assertThisEqualToThis() {
assertThis();
assertThis();
}

@Override
public void areDifferentThan() {
allGroups.add(currentGroup.get());
currentGroup.set(new ArrayList<>());
}
};
setupTest(api);
List<Object> lastGroup = currentGroup.get();
if (!lastGroup.isEmpty()) {
throw new IllegalArgumentException("Looks like you forgot to make a final call to 'areDifferentThan()'.");
}
EqualsTester tester = new EqualsTester();
for (List<Object> step : allGroups) {
tester.addEqualityGroup(step.toArray());
}
tester.testEquals();
}
}
64 changes: 64 additions & 0 deletions testlib/src/main/java/com/diffplug/spotless/TestProvisioner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2016 DiffPlug
*
* 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 com.diffplug.spotless;

import java.io.File;
import java.util.function.Consumer;

import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.testfixtures.ProjectBuilder;

import com.diffplug.common.base.StandardSystemProperty;

public class TestProvisioner {
/**
* Creates a Provisioner for the given repositories.
*
* The first time a project is created, there are ~7 seconds of configuration
* which will go away for all subsequent runs.
*
* Every call to resolve will take about 1 second, even when all artifacts are resolved.
*/
private static Provisioner createWithRepositories(Consumer<RepositoryHandler> repoConfig) {
// use the default gradle home directory to ensure that files are always resolved to the same location
File gradleHome = new File(StandardSystemProperty.USER_DIR.value() + "/.gradle");
Project project = ProjectBuilder.builder()
.withGradleUserHomeDir(gradleHome)
.build();
repoConfig.accept(project.getRepositories());
return mavenCoords -> {
Dependency[] deps = mavenCoords.stream()
.map(project.getDependencies()::create)
.toArray(Dependency[]::new);
Configuration config = project.getConfigurations().detachedConfiguration(deps);
config.setDescription(mavenCoords.toString());
return config.resolve();
};
}

/** Creates a Provisioner for the jcenter repo. */
public static Provisioner jcenter() {
return createWithRepositories(repo -> repo.jcenter());
}

/** Creates a Provisioner for the mavenCentral repo. */
public static Provisioner mavenCentral() {
return createWithRepositories(repo -> repo.mavenCentral());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2016 DiffPlug
*
* 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 com.diffplug.spotless.markdown;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.StepEqualityTester;
import com.diffplug.spotless.StepHarness;
import com.diffplug.spotless.TestProvisioner;

public class FreshMarkStepTest {
@Test
public void behavior() throws Exception {
HashMap<String, String> map = new HashMap<>();
map.put("lib", "MyLib");
map.put("author", "Me");
StepHarness.forStep(FreshMarkStep.create(() -> map, TestProvisioner.mavenCentral()))
.testResource("freshmark/FreshMarkUnformatted.test", "freshmark/FreshMarkFormatted.test");
}

@Test
public void equality() throws Exception {
new StepEqualityTester() {
String version = "1.3.1";
Map<String, Object> props = new HashMap<>();

@Override
protected void setupTest(API api) {
// same version and props == same
api.assertThisEqualToThis();
api.areDifferentThan();
// change the version, and it's different
version = "1.3.0";
api.assertThisEqualToThis();
api.areDifferentThan();
// change the props, and it's different
props.put("1", "2");
api.assertThisEqualToThis();
api.areDifferentThan();
}

@Override
protected FormatterStep create() {
String finalVersion = this.version;
Map<String, ?> finalProps = new HashMap<>(props);
return FreshMarkStep.create(finalVersion, () -> finalProps, TestProvisioner.mavenCentral());
}
}.testEquals();
}
}
15 changes: 15 additions & 0 deletions testlib/src/test/resources/freshmark/FreshMarkFormatted.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!---freshmark shields
output = link(shield('License Apache', 'license', 'Apache', 'brightgreen'), 'https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)');
-->
[![License Apache](https://img.shields.io/badge/license-Apache-brightgreen.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))
<!---freshmark /shields -->

Unformatted stuff.

<!---freshmark props
output = 'lib=' + lib + ' author=' + author;
-->
lib=MyLib author=Me
<!---freshmark /props -->


15 changes: 15 additions & 0 deletions testlib/src/test/resources/freshmark/FreshMarkUnformatted.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!---freshmark shields
output = link(shield('License Apache', 'license', 'Apache', 'brightgreen'), 'https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)');
-->
[![License Apache](https://img.shields.io/badge/license-Apache-blue.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))
<!---freshmark /shields -->

Unformatted stuff.

<!---freshmark props
output = 'lib=' + lib + ' author=' + author;
-->

<!---freshmark /props -->


0 comments on commit a060ee4

Please sign in to comment.