/
githubmirror
/
RxJava
Обзор
Документация
Войти
/
githubmirror
/
RxJava
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
4.x
src/test/java/io/reactivex/rxjava4/validators/CheckParamValidationNamingTest.java
555 строк
24 KB
David Karnok
4.x: Streamable ~ take native implementation (#8226)
09 июл 2026, 09:04
Не верифицирован
09 июл 2026, 09:04
7e8b750
Код
Авторство
О чём код?
/* * Copyright (c) 2016-present, RxJava Contributors. * * 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 io.reactivex.rxjava4.validators; import java.io.File; import java.nio.file.Files; import java.util.*; import org.junit.jupiter.api.Test; import io.reactivex.rxjava4.core.*; import io.reactivex.rxjava4.core.Observable; import io.reactivex.rxjava4.disposables.*; import io.reactivex.rxjava4.parallel.ParallelFlowable; import io.reactivex.rxjava4.processors.*; import io.reactivex.rxjava4.schedulers.Schedulers; import io.reactivex.rxjava4.subjects.*; import io.reactivex.rxjava4.testsupport.TestHelper; /** * Check if the parameter name in Objects.requireNonNull * and ObjectHelper.verifyPositive calls match the parameter * name in the message. */ public class CheckParamValidationNamingTest extends RxJavaTest { @Test public void checkCompletable() throws Exception { processFile(Completable.class); } @Test public void checkSingle() throws Exception { processFile(Single.class); } @Test public void checkMaybe() throws Exception { processFile(Maybe.class); } @Test public void checkObservable() throws Exception { processFile(Observable.class); } @Test public void checkFlowable() throws Exception { processFile(Flowable.class); } @Test public void checkParallelFlowable() throws Exception { processFile(ParallelFlowable.class); } @Test public void checkConnectableObservable() throws Exception { processFile(ConnectableObservable.class); } @Test public void checkConnectableFlowable() throws Exception { processFile(ConnectableFlowable.class); } @Test public void checkSubject() throws Exception { processFile(Subject.class); } @Test public void checkFlowableProcessor() throws Exception { processFile(FlowableProcessor.class); } @Test public void checkDisposable() throws Exception { processFile(Disposable.class); } @Test public void checkScheduler() throws Exception { processFile(Scheduler.class); } @Test public void checkSchedulers() throws Exception { processFile(Schedulers.class); } @Test public void checkAsyncSubject() throws Exception { processFile(AsyncSubject.class); } @Test public void checkBehaviorSubject() throws Exception { processFile(BehaviorSubject.class); } @Test public void checkPublishSubject() throws Exception { processFile(PublishSubject.class); } @Test public void checkReplaySubject() throws Exception { processFile(ReplaySubject.class); } @Test public void checkUnicastSubject() throws Exception { processFile(UnicastSubject.class); } @Test public void checkSingleSubject() throws Exception { processFile(SingleSubject.class); } @Test public void checkMaybeSubject() throws Exception { processFile(MaybeSubject.class); } @Test public void checkCompletableSubject() throws Exception { processFile(CompletableSubject.class); } @Test public void checkAsyncProcessor() throws Exception { processFile(AsyncProcessor.class); } @Test public void checkBehaviorProcessor() throws Exception { processFile(BehaviorProcessor.class); } @Test public void checkPublishProcessor() throws Exception { processFile(PublishProcessor.class); } @Test public void checkReplayProcessor() throws Exception { processFile(ReplayProcessor.class); } @Test public void checkUnicastProcessor() throws Exception { processFile(UnicastProcessor.class); } @Test public void checkMulticastProcessor() throws Exception { processFile(MulticastProcessor.class); } @Test public void checkCompositeDisposable() throws Exception { processFile(CompositeDisposable.class); } @Test public void checkStreamable() throws Exception { processFile(Streamable.class); } static void processFile(Class<?> clazz) throws Exception { String baseClassName = clazz.getSimpleName(); File f = TestHelper.findSource(baseClassName, clazz.getPackage().getName()); if (f == null) { return; } String fullClassName = clazz.getName(); int errorCount = 0; StringBuilder errors = new StringBuilder(); List<String> lines = Files.readAllLines(f.toPath()); for (int j = 0; j < lines.size(); j++) { String line = lines.get(j).trim(); for (ValidatorStrings validatorStr : VALIDATOR_STRINGS) { int strIdx = line.indexOf(validatorStr.code); if (strIdx >= 0) { int comma = line.indexOf(',', strIdx + validatorStr.code.length()); String paramName = line.substring(strIdx + validatorStr.code.length(), comma); int quote = line.indexOf('"', comma); String message = line.substring(quote + 1, Math.min(line.length(), quote + 2 + paramName.length())); if (line.contains("\"A Disposable")) { continue; } if (!line.contains("\"The RxJavaPlugins") && !(message.startsWith(paramName) && (message.endsWith(" ") || message.endsWith("\"")))) { errorCount++; errors.append("L") .append(j) .append(" : Wrong validator message parameter name\r\n ") .append(line) .append("\r\n") .append(" ").append(paramName).append(" != ").append(message) .append("\r\n at ") .append(fullClassName) .append(".method(") .append(f.getName()) .append(":") .append(j + 1) .append(")\r\n") ; } int midx = j - 1; // find the method declaration for (; midx >= 0; midx--) { String linek = lines.get(midx).trim(); if (linek.startsWith("public") || linek.startsWith("private") || linek.startsWith("protected") || linek.startsWith("static") || linek.startsWith("default") || linek.startsWith(baseClassName)) { break; } } if (line.contains("\"The RxJavaPlugins")) { continue; } // find Javadoc of throws boolean found = false; for (int k = midx - 1; k >= 0; k--) { String linek = lines.get(k).trim(); if (linek.startsWith("/** {@inheritDoc} */")) { found = true; // the docs in the sealed doc class, skip the check break; } if (linek.startsWith("/**")) { break; } if (linek.startsWith("}")) { found = true; // no method Javadoc present break; } if (linek.startsWith(validatorStr.javadoc)) { // see if a @code paramName is present String paramStr = "{@code " + paramName + "}"; for (int m = k; m < lines.size(); m++) { String linem = lines.get(m).trim(); if (linem.startsWith("* @see") || linem.startsWith("* @since") || linem.startsWith("*/")) { break; } if (linem.contains(paramStr)) { found = true; break; } } break; } } if (!found) { errorCount++; errors.append("L") .append(j) .append(" : missing '") .append(validatorStr.javadoc) .append("' for argument validation: ") .append(paramName) .append("\r\n ") .append(line) .append("\r\n at ") .append(fullClassName) .append(".method(") .append(f.getName()) .append(":") .append(j + 1) .append(")\r\n") ; } } } for (ValidatorStrings validatorStr : EXCEPTION_STRINGS) { int strIdx = line.indexOf(validatorStr.code); if (strIdx >= 0) { int midx = j - 1; // find the method declaration for (; midx >= 0; midx--) { String linek = lines.get(midx).trim(); if (linek.startsWith("public") || linek.startsWith("private") || linek.startsWith("protected") || linek.startsWith("static") || linek.startsWith("default") || linek.startsWith(baseClassName)) { break; } } // find Javadoc of throws boolean found = false; for (int k = midx - 1; k >= 0; k--) { String linek = lines.get(k).trim(); if (linek.startsWith("/**")) { break; } if (linek.startsWith("}")) { found = true; // no Javadoc break; } if (linek.startsWith(validatorStr.javadoc)) { found = true; } } if (!found) { errorCount++; errors.append("L") .append(j) .append(" : missing '") .append(validatorStr.javadoc) .append("' for exception\r\n ") .append(line) .append("\r\n at ") .append(fullClassName) .append(".method(") .append(f.getName()) .append(":") .append(j + 1) .append(")\r\n") ; } } } if (line.startsWith("public") || line.startsWith("protected") || line.startsWith("final") || line.startsWith("private") || line.startsWith("static") || line.startsWith("default")) { for (ValidatorStrings validatorStr : TYPICAL_ARGUMENT_STRINGS) { // find the method declaration ending { for (int i = j; i < lines.size(); i++) { String linei = lines.get(i).trim(); // space + code for capturing type declarations String varPattern = " " + validatorStr.code; if (linei.contains(varPattern + ")") || linei.contains(varPattern + ",") || linei.endsWith(varPattern)) { // ignore nullable-annotated arguments if (!linei.matches(".*@Nullable\\s.*" + validatorStr.code + ".*")) { boolean found = false; for (int k = i - 1; k >= 0; k--) { String linek = lines.get(k).trim(); if (linek.startsWith("/** {@inheritDoc} */")) { found = true; break; // the document is in the sealed doc interface } if (linek.startsWith("/**")) { break; } if (linek.startsWith("}")) { found = true; // no method Javadoc present break; } if (linek.startsWith(validatorStr.javadoc)) { // see if a @code paramName is present String paramStr = "{@code " + validatorStr.code + "}"; for (int m = k; m < lines.size(); m++) { String linem = lines.get(m).trim(); if (linem.startsWith("* @see") || linem.startsWith("* @since") || linem.startsWith("*/")) { break; } if (linem.contains(paramStr)) { found = true; break; } } break; } } if (!found) { errorCount++; errors.append("L") .append(j) .append(" : missing '") .append(validatorStr.javadoc) .append("' for typical argument: ") .append(validatorStr.code) .append("\r\n ") .append(line) .append("\r\n at ") .append(fullClassName) .append(".method(") .append(f.getName()) .append(":") .append(j + 1) .append(")\r\n") ; } } } if (linei.endsWith("{") || linei.endsWith(";")) { break; } } } } } if (errorCount != 0) { errors.insert(0, errorCount + " problems\r\n"); errors.setLength(errors.length() - 2); throw new AssertionError(errors.toString()); } } record ValidatorStrings(String code, String javadoc) { } static final List<ValidatorStrings> VALIDATOR_STRINGS = Arrays.asList( new ValidatorStrings("Objects.requireNonNull(", "* @throws NullPointerException"), new ValidatorStrings("ObjectHelper.verifyPositive(", "* @throws IllegalArgumentException") ); static final List<ValidatorStrings> EXCEPTION_STRINGS = Arrays.asList( new ValidatorStrings("throw new NullPointerException(", "* @throws NullPointerException"), new ValidatorStrings("throw new IllegalArgumentException(", "* @throws IllegalArgumentException"), new ValidatorStrings("throw new IndexOutOfBoundsException(", "* @throws IndexOutOfBoundsException") ); static final List<ValidatorStrings> TYPICAL_ARGUMENT_STRINGS = Arrays.asList( new ValidatorStrings("source", "* @throws NullPointerException"), new ValidatorStrings("source1", "* @throws NullPointerException"), new ValidatorStrings("source2", "* @throws NullPointerException"), new ValidatorStrings("source3", "* @throws NullPointerException"), new ValidatorStrings("source4", "* @throws NullPointerException"), new ValidatorStrings("source5", "* @throws NullPointerException"), new ValidatorStrings("source6", "* @throws NullPointerException"), new ValidatorStrings("source7", "* @throws NullPointerException"), new ValidatorStrings("source8", "* @throws NullPointerException"), new ValidatorStrings("source9", "* @throws NullPointerException"), new ValidatorStrings("sources", "* @throws NullPointerException"), new ValidatorStrings("mapper", "* @throws NullPointerException"), new ValidatorStrings("combiner", "* @throws NullPointerException"), new ValidatorStrings("zipper", "* @throws NullPointerException"), new ValidatorStrings("predicate", "* @throws NullPointerException"), new ValidatorStrings("item", "* @throws NullPointerException"), new ValidatorStrings("item1", "* @throws NullPointerException"), new ValidatorStrings("item2", "* @throws NullPointerException"), new ValidatorStrings("item3", "* @throws NullPointerException"), new ValidatorStrings("item4", "* @throws NullPointerException"), new ValidatorStrings("item5", "* @throws NullPointerException"), new ValidatorStrings("item6", "* @throws NullPointerException"), new ValidatorStrings("item7", "* @throws NullPointerException"), new ValidatorStrings("item8", "* @throws NullPointerException"), new ValidatorStrings("item9", "* @throws NullPointerException"), new ValidatorStrings("item10", "* @throws NullPointerException"), new ValidatorStrings("unit", "* @throws NullPointerException"), new ValidatorStrings("scheduler", "* @throws NullPointerException"), new ValidatorStrings("other", "* @throws NullPointerException"), new ValidatorStrings("fallback", "* @throws NullPointerException"), new ValidatorStrings("defaultItem", "* @throws NullPointerException"), new ValidatorStrings("defaultValue", "* @throws NullPointerException"), new ValidatorStrings("stop", "* @throws NullPointerException"), new ValidatorStrings("stopPredicate", "* @throws NullPointerException"), new ValidatorStrings("handler", "* @throws NullPointerException"), new ValidatorStrings("bufferSupplier", "* @throws NullPointerException"), new ValidatorStrings("openingIndicator", "* @throws NullPointerException"), new ValidatorStrings("closingIndicator", "* @throws NullPointerException"), new ValidatorStrings("boundary", "* @throws NullPointerException"), new ValidatorStrings("boundaryIndicator", "* @throws NullPointerException"), new ValidatorStrings("selector", "* @throws NullPointerException"), new ValidatorStrings("resultSelector", "* @throws NullPointerException"), new ValidatorStrings("keySelector", "* @throws NullPointerException"), new ValidatorStrings("valueSelector", "* @throws NullPointerException"), new ValidatorStrings("valueSupplier", "* @throws NullPointerException"), new ValidatorStrings("collectionSupplier", "* @throws NullPointerException"), new ValidatorStrings("onNext", "* @throws NullPointerException"), new ValidatorStrings("onError", "* @throws NullPointerException"), new ValidatorStrings("onComplete", "* @throws NullPointerException"), new ValidatorStrings("onEvent", "* @throws NullPointerException"), new ValidatorStrings("onAfterNext", "* @throws NullPointerException"), new ValidatorStrings("onAfterTerminate", "* @throws NullPointerException"), new ValidatorStrings("onTerminate", "* @throws NullPointerException"), new ValidatorStrings("onSuccess", "* @throws NullPointerException"), new ValidatorStrings("onSubscribe", "* @throws NullPointerException"), new ValidatorStrings("onNotification", "* @throws NullPointerException"), new ValidatorStrings("onCancel", "* @throws NullPointerException"), new ValidatorStrings("onDispose", "* @throws NullPointerException"), new ValidatorStrings("onRequest", "* @throws NullPointerException"), new ValidatorStrings("onNextMapper", "* @throws NullPointerException"), new ValidatorStrings("onErrorMapper", "* @throws NullPointerException"), new ValidatorStrings("onCompleteSupplier", "* @throws NullPointerException"), new ValidatorStrings("clazz", "* @throws NullPointerException"), new ValidatorStrings("next", "* @throws NullPointerException"), new ValidatorStrings("reducer", "* @throws NullPointerException"), new ValidatorStrings("seed", "* @throws NullPointerException"), new ValidatorStrings("seedSupplier", "* @throws NullPointerException"), new ValidatorStrings("mapSupplier", "* @throws NullPointerException"), new ValidatorStrings("collectionFactory", "* @throws NullPointerException"), new ValidatorStrings("factory", "* @throws NullPointerException"), new ValidatorStrings("stage", "* @throws NullPointerException"), new ValidatorStrings("stream", "* @throws NullPointerException"), new ValidatorStrings("collector", "* @throws NullPointerException"), new ValidatorStrings("subscriptionIndicator", "* @throws NullPointerException"), new ValidatorStrings("itemDelayIndicator", "* @throws NullPointerException"), new ValidatorStrings("future", "* @throws NullPointerException"), new ValidatorStrings("maxConcurrency", "* @throws IllegalArgumentException"), new ValidatorStrings("parallelism", "* @throws IllegalArgumentException"), new ValidatorStrings("prefetch", "* @throws IllegalArgumentException"), new ValidatorStrings("bufferSize", "* @throws IllegalArgumentException"), new ValidatorStrings("capacityHint", "* @throws IllegalArgumentException"), new ValidatorStrings("capacity", "* @throws IllegalArgumentException"), new ValidatorStrings("count", "* @throws IllegalArgumentException"), new ValidatorStrings("skip", "* @throws IllegalArgumentException"), new ValidatorStrings("times", "* @throws IllegalArgumentException"), new ValidatorStrings("n", "* @throws IllegalArgumentException") ); }