| 
 | 1 | +/*  | 
 | 2 | + * Copyright (c) 2011-2024 Qulice.com  | 
 | 3 | + *  | 
 | 4 | + * All rights reserved.  | 
 | 5 | + *  | 
 | 6 | + * Redistribution and use in source and binary forms, with or without  | 
 | 7 | + * modification, are permitted provided that the following conditions  | 
 | 8 | + * are met: 1) Redistributions of source code must retain the above  | 
 | 9 | + * copyright notice, this list of conditions and the following  | 
 | 10 | + * disclaimer. 2) Redistributions in binary form must reproduce the above  | 
 | 11 | + * copyright notice, this list of conditions and the following  | 
 | 12 | + * disclaimer in the documentation and/or other materials provided  | 
 | 13 | + * with the distribution. 3) Neither the name of the Qulice.com nor  | 
 | 14 | + * the names of its contributors may be used to endorse or promote  | 
 | 15 | + * products derived from this software without specific prior written  | 
 | 16 | + * permission.  | 
 | 17 | + *  | 
 | 18 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  | 
 | 19 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  | 
 | 20 | + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND  | 
 | 21 | + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  | 
 | 22 | + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  | 
 | 23 | + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES  | 
 | 24 | + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR  | 
 | 25 | + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | 
 | 26 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  | 
 | 27 | + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  | 
 | 28 | + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  | 
 | 29 | + * OF THE POSSIBILITY OF SUCH DAMAGE.  | 
 | 30 | + */  | 
 | 31 | +package com.qulice.checkstyle;  | 
 | 32 | + | 
 | 33 | +import com.qulice.spi.Environment;  | 
 | 34 | +import com.qulice.spi.Violation;  | 
 | 35 | +import java.io.File;  | 
 | 36 | +import java.io.IOException;  | 
 | 37 | +import java.util.Collection;  | 
 | 38 | +import org.cactoos.io.ResourceOf;  | 
 | 39 | +import org.cactoos.text.FormattedText;  | 
 | 40 | +import org.cactoos.text.IoCheckedText;  | 
 | 41 | +import org.cactoos.text.TextOf;  | 
 | 42 | +import org.hamcrest.Description;  | 
 | 43 | +import org.hamcrest.MatcherAssert;  | 
 | 44 | +import org.hamcrest.Matchers;  | 
 | 45 | +import org.hamcrest.TypeSafeMatcher;  | 
 | 46 | +import org.junit.jupiter.api.BeforeEach;  | 
 | 47 | +import org.junit.jupiter.api.Test;  | 
 | 48 | + | 
 | 49 | +/**  | 
 | 50 | + * Test case for file metainfo validation.  | 
 | 51 | + * @since 0.3  | 
 | 52 | + */  | 
 | 53 | +@SuppressWarnings(  | 
 | 54 | +    {  | 
 | 55 | +        "PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals", "PMD.GodClass"  | 
 | 56 | +    }  | 
 | 57 | +)  | 
 | 58 | +final class ChecksMetainfoTest {  | 
 | 59 | + | 
 | 60 | +    /**  | 
 | 61 | +     * Name of property to set to change location of the license.  | 
 | 62 | +     */  | 
 | 63 | +    private static final String LICENSE_PROP = "license";  | 
 | 64 | + | 
 | 65 | +    /**  | 
 | 66 | +     * Directory with classes.  | 
 | 67 | +     */  | 
 | 68 | +    private static final String DIRECTORY = "src/main/java/foo";  | 
 | 69 | + | 
 | 70 | +    /**  | 
 | 71 | +     * License text.  | 
 | 72 | +     */  | 
 | 73 | +    private static final String LICENSE = "Hello.";  | 
 | 74 | + | 
 | 75 | +    /**  | 
 | 76 | +     * Rule for testing.  | 
 | 77 | +     */  | 
 | 78 | +    private License rule;  | 
 | 79 | + | 
 | 80 | +    @BeforeEach  | 
 | 81 | +    public void setRule() {  | 
 | 82 | +        this.rule = new License();  | 
 | 83 | +    }  | 
 | 84 | + | 
 | 85 | +    /**  | 
 | 86 | +     * CheckstyleValidator can deny binary contents in java file.  | 
 | 87 | +     * This is test for #1264.  | 
 | 88 | +     * @throws Exception If something wrong happens inside  | 
 | 89 | +     */  | 
 | 90 | +    @Test  | 
 | 91 | +    void rejectsJavaFileWithBinaryContent() throws Exception {  | 
 | 92 | +        this.runValidation("JavaFileWithBinaryContent.java", false);  | 
 | 93 | +    }  | 
 | 94 | + | 
 | 95 | +    /**  | 
 | 96 | +     * Returns string with Checkstyle validation results.  | 
 | 97 | +     * @param file File to check.  | 
 | 98 | +     * @param passes Whether validation is expected to pass.  | 
 | 99 | +     * @return String containing validation results in textual form.  | 
 | 100 | +     * @throws IOException In case of error  | 
 | 101 | +     */  | 
 | 102 | +    @SuppressWarnings("PMD.JUnitAssertionsShouldIncludeMessage")  | 
 | 103 | +    private Collection<Violation> runValidation(final String file,  | 
 | 104 | +        final boolean passes) throws IOException {  | 
 | 105 | +        final Environment.Mock mock = new Environment.Mock();  | 
 | 106 | +        final File license = this.rule.savePackageInfo(  | 
 | 107 | +            new File(mock.basedir(), ChecksMetainfoTest.DIRECTORY)  | 
 | 108 | +        ).withLines(ChecksMetainfoTest.LICENSE)  | 
 | 109 | +            .withEol("\n").file();  | 
 | 110 | +        final Environment env = mock.withParam(  | 
 | 111 | +            ChecksMetainfoTest.LICENSE_PROP,  | 
 | 112 | +            this.toUrl(license)  | 
 | 113 | +        )  | 
 | 114 | +            .withFile(  | 
 | 115 | +                String.format("src/main/java/foo/%s", file),  | 
 | 116 | +                new IoCheckedText(  | 
 | 117 | +                    new TextOf(  | 
 | 118 | +                        new ResourceOf(  | 
 | 119 | +                            new FormattedText("com/qulice/checkstyle/%s", file)  | 
 | 120 | +                        )  | 
 | 121 | +                    )  | 
 | 122 | +                ).asString()  | 
 | 123 | +            );  | 
 | 124 | +        final Collection<Violation> results =  | 
 | 125 | +            new CheckstyleValidator(env).validate(  | 
 | 126 | +                env.files(file)  | 
 | 127 | +            );  | 
 | 128 | +        if (passes) {  | 
 | 129 | +            MatcherAssert.assertThat(  | 
 | 130 | +                results,  | 
 | 131 | +                Matchers.<Violation>empty()  | 
 | 132 | +            );  | 
 | 133 | +        } else {  | 
 | 134 | +            MatcherAssert.assertThat(  | 
 | 135 | +                results,  | 
 | 136 | +                Matchers.not(Matchers.<Violation>empty())  | 
 | 137 | +            );  | 
 | 138 | +        }  | 
 | 139 | +        return results;  | 
 | 140 | +    }  | 
 | 141 | + | 
 | 142 | +    /**  | 
 | 143 | +     * Convert file name to URL.  | 
 | 144 | +     * @param file The file  | 
 | 145 | +     * @return The URL  | 
 | 146 | +     */  | 
 | 147 | +    private String toUrl(final File file) {  | 
 | 148 | +        return String.format("file:%s", file);  | 
 | 149 | +    }  | 
 | 150 | + | 
 | 151 | +    /**  | 
 | 152 | +     * Validation results matcher.  | 
 | 153 | +     *  | 
 | 154 | +     * @since 0.1  | 
 | 155 | +     */  | 
 | 156 | +    private static final class ViolationMatcher extends  | 
 | 157 | +        TypeSafeMatcher<Violation> {  | 
 | 158 | + | 
 | 159 | +        /**  | 
 | 160 | +         * Message to check.  | 
 | 161 | +         */  | 
 | 162 | +        private final String message;  | 
 | 163 | + | 
 | 164 | +        /**  | 
 | 165 | +         * File to check.  | 
 | 166 | +         */  | 
 | 167 | +        private final String file;  | 
 | 168 | + | 
 | 169 | +        /**  | 
 | 170 | +         * Expected line.  | 
 | 171 | +         */  | 
 | 172 | +        private final String line;  | 
 | 173 | + | 
 | 174 | +        /**  | 
 | 175 | +         * Check name.  | 
 | 176 | +         */  | 
 | 177 | +        private final String check;  | 
 | 178 | + | 
 | 179 | +        /**  | 
 | 180 | +         * Constructor.  | 
 | 181 | +         * @param message Message to check  | 
 | 182 | +         * @param file File to check  | 
 | 183 | +         * @param line Line to check  | 
 | 184 | +         * @param check Check name  | 
 | 185 | +         * @checkstyle ParameterNumber (3 lines)  | 
 | 186 | +         */  | 
 | 187 | +        ViolationMatcher(final String message, final String file,  | 
 | 188 | +            final String line, final String check) {  | 
 | 189 | +            super();  | 
 | 190 | +            this.message = message;  | 
 | 191 | +            this.file = file;  | 
 | 192 | +            this.line = line;  | 
 | 193 | +            this.check = check;  | 
 | 194 | +        }  | 
 | 195 | + | 
 | 196 | +        /**  | 
 | 197 | +         * Constructor.  | 
 | 198 | +         * @param message Message to check  | 
 | 199 | +         * @param file File to check  | 
 | 200 | +         */  | 
 | 201 | +        ViolationMatcher(final String message, final String file) {  | 
 | 202 | +            this(message, file, "", "");  | 
 | 203 | +        }  | 
 | 204 | + | 
 | 205 | +        @Override  | 
 | 206 | +        public boolean matchesSafely(final Violation item) {  | 
 | 207 | +            return item.message().contains(this.message)  | 
 | 208 | +                && item.file().endsWith(this.file)  | 
 | 209 | +                && this.lineMatches(item)  | 
 | 210 | +                && this.checkMatches(item);  | 
 | 211 | +        }  | 
 | 212 | + | 
 | 213 | +        @Override  | 
 | 214 | +        public void describeTo(final Description description) {  | 
 | 215 | +            description.appendText("doesn't match");  | 
 | 216 | +        }  | 
 | 217 | + | 
 | 218 | +        /**  | 
 | 219 | +         * Check name matches.  | 
 | 220 | +         * @param item Item to check.  | 
 | 221 | +         * @return True if check name matches.  | 
 | 222 | +         */  | 
 | 223 | +        private boolean checkMatches(final Violation item) {  | 
 | 224 | +            return this.check.isEmpty()  | 
 | 225 | +                || !this.check.isEmpty() && item.name().equals(this.check);  | 
 | 226 | +        }  | 
 | 227 | + | 
 | 228 | +        /**  | 
 | 229 | +         * Check that given line matches.  | 
 | 230 | +         * @param item Item to check.  | 
 | 231 | +         * @return True if line matches.  | 
 | 232 | +         */  | 
 | 233 | +        private boolean lineMatches(final Violation item) {  | 
 | 234 | +            return this.line.isEmpty()  | 
 | 235 | +                || !this.line.isEmpty() && item.lines().equals(this.line);  | 
 | 236 | +        }  | 
 | 237 | +    }  | 
 | 238 | +}  | 
0 commit comments