| /* |
| * Copyright (c) 2014, the Dart project authors. |
| * |
| * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html |
| * |
| * 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.google.dart.server.internal; |
| |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Maps; |
| import com.google.dart.engine.source.Source; |
| import com.google.dart.engine.utilities.general.ArrayUtilities; |
| import com.google.dart.server.AnalysisServerListener; |
| import com.google.dart.server.CompletionSuggestion; |
| import com.google.dart.server.Outline; |
| import com.google.dart.server.SearchResult; |
| import com.google.dart.server.generated.types.AnalysisError; |
| import com.google.dart.server.generated.types.AnalysisStatus; |
| import com.google.dart.server.generated.types.Element; |
| import com.google.dart.server.generated.types.HighlightRegion; |
| import com.google.dart.server.generated.types.NavigationRegion; |
| import com.google.dart.server.generated.types.Occurrences; |
| import com.google.dart.server.generated.types.OverrideMember; |
| import com.google.dart.server.internal.asserts.NavigationRegionsAssert; |
| |
| import junit.framework.Assert; |
| import junit.framework.AssertionFailedError; |
| |
| import static org.fest.assertions.Assertions.assertThat; |
| |
| import java.util.List; |
| import java.util.Map; |
| |
| public class TestAnalysisServerListener implements AnalysisServerListener { |
| |
| private final static class CompletionResult { |
| final int replacementOffset; |
| final int replacementLength; |
| final CompletionSuggestion[] suggestions; |
| final boolean last; |
| |
| public CompletionResult(int replacementOffset, int replacementLength, |
| CompletionSuggestion[] suggestions, boolean last) { |
| this.replacementOffset = replacementOffset; |
| this.replacementLength = replacementLength; |
| this.suggestions = suggestions; |
| this.last = last; |
| } |
| } |
| |
| private final Map<String, CompletionResult> completionsMap = Maps.newHashMap(); |
| private final List<String> flushedResults = Lists.newArrayList(); |
| private final Map<String, SearchResult[]> searchResultsMap = Maps.newHashMap(); |
| private final List<AnalysisServerError> serverErrors = Lists.newArrayList(); |
| private final Map<String, AnalysisError[]> sourcesErrors = Maps.newHashMap(); |
| private final Map<String, HighlightRegion[]> highlightsMap = Maps.newHashMap(); |
| private final Map<String, NavigationRegion[]> navigationMap = Maps.newHashMap(); |
| private final Map<String, Occurrences[]> occurrencesMap = Maps.newHashMap(); |
| private final Map<String, Outline> outlineMap = Maps.newHashMap(); |
| private final Map<String, OverrideMember[]> overridesMap = Maps.newHashMap(); |
| private boolean serverConnected = false; |
| private AnalysisStatus analysisStatus = null; |
| |
| public synchronized void assertAnalysisStatus(AnalysisStatus expectedStatus) { |
| Assert.assertEquals(expectedStatus.isAnalyzing(), analysisStatus.isAnalyzing()); |
| Assert.assertEquals(expectedStatus.getAnalysisTarget(), analysisStatus.getAnalysisTarget()); |
| } |
| |
| /** |
| * Assert that the number of errors that have been gathered matches the number of errors that are |
| * given and that they have the expected error codes. The order in which the errors were gathered |
| * is ignored. |
| * |
| * @param file the file to check errors for |
| * @param expectedErrorCodes the error codes of the errors that should have been gathered |
| * @throws AssertionFailedError if a different number of errors have been gathered than were |
| * expected |
| */ |
| public synchronized void assertErrorsWithAnalysisErrors(String file, |
| AnalysisError... expectedErrors) { |
| AnalysisError[] errors = getErrors(file); |
| assertErrorsWithAnalysisErrors(errors, expectedErrors); |
| } |
| |
| /** |
| * Asserts the list of flushed results. |
| */ |
| public synchronized void assertFlushedResults(List<String> expectedFlushedResults) { |
| assertThat(expectedFlushedResults).isEqualTo(flushedResults); |
| } |
| |
| /** |
| * Returns {@link NavigationRegionsAssert} for the given file. |
| */ |
| public synchronized NavigationRegionsAssert assertNavigationRegions(String file) { |
| return new NavigationRegionsAssert(getNavigationRegions(file)); |
| } |
| |
| /** |
| * Asserts that there was no {@link AnalysisServerError} reported. |
| */ |
| public synchronized void assertNoServerErrors() { |
| assertThat(serverErrors).isEmpty(); |
| } |
| |
| public synchronized void assertServerConnected(boolean expectedConnected) { |
| Assert.assertEquals(expectedConnected, serverConnected); |
| } |
| |
| public void assertServerErrors(List<AnalysisServerError> expectedErrors) { |
| Assert.assertEquals(expectedErrors.size(), serverErrors.size()); |
| for (int i = 0; i < expectedErrors.size(); i++) { |
| Assert.assertTrue(expectedErrors.get(i).equals(serverErrors.get(i))); |
| } |
| } |
| |
| /** |
| * Removes all of reported {@link NavigationRegion}s. |
| */ |
| public synchronized void clearNavigationRegions() { |
| navigationMap.clear(); |
| } |
| |
| /** |
| * Removes all of reported {@link Occurrences}s. |
| */ |
| public synchronized void clearOccurrences() { |
| occurrencesMap.clear(); |
| } |
| |
| /** |
| * Removes all of reported {@link OverrideMember}. |
| */ |
| public synchronized void clearOverrides() { |
| overridesMap.clear(); |
| } |
| |
| @Override |
| public synchronized void computedCompletion(String completionId, int replacementOffset, |
| int replacementLength, CompletionSuggestion[] suggestions, boolean last) { |
| // computed completion results are aggregate, replacing any prior results |
| completionsMap.put(completionId, new CompletionResult( |
| replacementOffset, |
| replacementLength, |
| suggestions, |
| last)); |
| } |
| |
| @Override |
| public synchronized void computedErrors(String file, AnalysisError[] errors) { |
| sourcesErrors.put(file, errors); |
| } |
| |
| @Override |
| public synchronized void computedHighlights(String file, HighlightRegion[] highlights) { |
| highlightsMap.put(file, highlights); |
| } |
| |
| @Override |
| public synchronized void computedNavigation(String file, NavigationRegion[] targets) { |
| navigationMap.put(file, targets); |
| } |
| |
| @Override |
| public void computedOccurrences(String file, Occurrences[] occurrencesArray) { |
| occurrencesMap.put(file, occurrencesArray); |
| } |
| |
| @Override |
| public synchronized void computedOutline(String file, Outline outline) { |
| outlineMap.put(file, outline); |
| } |
| |
| @Override |
| public void computedOverrides(String file, OverrideMember[] overrides) { |
| overridesMap.put(file, overrides); |
| } |
| |
| @Override |
| public void computedSearchResults(String searchId, SearchResult[] results, boolean last) { |
| searchResultsMap.put(searchId, results); |
| } |
| |
| /** |
| * Returns a navigation {@link Element} at the given position. |
| */ |
| public synchronized Element findNavigationElement(String file, int offset) { |
| NavigationRegion[] regions = getNavigationRegions(file); |
| if (regions != null) { |
| for (NavigationRegion navigationRegion : regions) { |
| if (navigationRegion.containsInclusive(offset)) { |
| return navigationRegion.getTargets().get(0); |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public synchronized void flushedResults(List<String> files) { |
| flushedResults.addAll(files); |
| } |
| |
| public boolean getCompletionIsLast(String completionId) { |
| CompletionResult result = completionsMap.get(completionId); |
| if (result == null) { |
| throw new AssertionFailedError("Expected completion response: " + completionId); |
| } |
| return result.last; |
| } |
| |
| public int getCompletionReplacementLength(String completionId) { |
| CompletionResult result = completionsMap.get(completionId); |
| if (result == null) { |
| throw new AssertionFailedError("Expected completion response: " + completionId); |
| } |
| return result.replacementLength; |
| } |
| |
| public int getCompletionReplacementOffset(String completionId) { |
| CompletionResult result = completionsMap.get(completionId); |
| if (result == null) { |
| throw new AssertionFailedError("Expected completion response: " + completionId); |
| } |
| return result.replacementOffset; |
| } |
| |
| /** |
| * Returns {@link CompletionSuggestion[]} for the given completion id, maybe {@code null} if have |
| * not been ever notified. |
| */ |
| public synchronized CompletionSuggestion[] getCompletions(String completionId) { |
| CompletionResult result = completionsMap.get(completionId); |
| return result != null ? result.suggestions : null; |
| } |
| |
| /** |
| * Returns {@link AnalysisError} for the given file, may be empty, but not {@code null}. |
| */ |
| public synchronized AnalysisError[] getErrors(String file) { |
| AnalysisError[] errors = sourcesErrors.get(file); |
| if (errors == null) { |
| return AnalysisError.EMPTY_ARRAY; |
| } |
| return errors; |
| } |
| |
| /** |
| * Returns {@link HighlightRegion}s for the given file, maybe {@code null} if have not been ever |
| * notified. |
| */ |
| public synchronized HighlightRegion[] getHighlightRegions(String file) { |
| return highlightsMap.get(file); |
| } |
| |
| /** |
| * Returns {@link NavigationRegion}s for the given file, maybe {@code null} if have not been ever |
| * notified. |
| */ |
| public synchronized NavigationRegion[] getNavigationRegions(String file) { |
| return navigationMap.get(file); |
| } |
| |
| /** |
| * Returns {@link Occurrences}s for the given file, maybe {@code null} if have not been ever |
| * notified. |
| */ |
| public synchronized Occurrences[] getOccurrences(String file) { |
| return occurrencesMap.get(file); |
| } |
| |
| /** |
| * Returns {@link Outline} for the given {@link Source}, maybe {@code null} if have not been ever |
| * notified. |
| */ |
| public synchronized Outline getOutline(String file) { |
| return outlineMap.get(file); |
| } |
| |
| /** |
| * Returns {@link OverrideMember}s for the given file, maybe {@code null} if have not been ever |
| * notified. |
| */ |
| public synchronized OverrideMember[] getOverrides(String file) { |
| return overridesMap.get(file); |
| } |
| |
| /** |
| * Returns {@link SearchResult[]} for the given search id, maybe {@code null} if have not been |
| * ever notified. |
| */ |
| public SearchResult[] getSearchResults(String searchId) { |
| return searchResultsMap.get(searchId); |
| } |
| |
| @Override |
| public synchronized void serverConnected() { |
| serverConnected = true; |
| } |
| |
| @Override |
| public synchronized void serverError(boolean isFatal, String message, String stackTrace) { |
| serverErrors.add(new AnalysisServerError(isFatal, message, stackTrace)); |
| } |
| |
| @Override |
| public synchronized void serverStatus(AnalysisStatus status) { |
| this.analysisStatus = status; |
| } |
| |
| /** |
| * Assert that the array of actual {@link AnalysisError}s match the array of expected |
| * {@link AnalysisError}s. |
| * |
| * @param actualErrors the actual set of errors that were created for some analysis |
| * @param expectedErrors the expected array of errors |
| */ |
| private void assertErrorsWithAnalysisErrors(AnalysisError[] actualErrors, |
| AnalysisError[] expectedErrors) { |
| if (actualErrors == null && expectedErrors == null) { |
| return; |
| } |
| |
| // assert that the arrays have the same length |
| Assert.assertEquals(expectedErrors.length, actualErrors.length); |
| |
| // assert that the actualErrors contains all of the expected errors |
| for (AnalysisError expectedError : expectedErrors) { |
| // individual calls to assert each error are made for better messaging when there is a failure |
| Assert.assertTrue(ArrayUtilities.contains(actualErrors, expectedError)); |
| } |
| } |
| } |