View Javadoc

1   package com.atlassian.selenium.visualcomparison.v2;
2   
3   import com.atlassian.annotations.ExperimentalApi;
4   import com.atlassian.selenium.visualcomparison.v2.settings.PagePart;
5   import com.atlassian.selenium.visualcomparison.v2.settings.Replacement;
6   import com.atlassian.selenium.visualcomparison.v2.settings.Resolution;
7   import com.google.common.collect.ImmutableList;
8   import com.google.common.collect.ImmutableSortedSet;
9   
10  import javax.annotation.Nonnull;
11  import javax.annotation.Nullable;
12  import javax.annotation.concurrent.Immutable;
13  import java.io.File;
14  import java.util.Set;
15  
16  import static com.google.common.base.Preconditions.checkNotNull;
17  import static java.util.Arrays.asList;
18  
19  /**
20   * Represents settings used for visual comparison. This is in essence an immutable bean that holds various settings.
21   *
22   * <p/>
23   * A single instance of code {@code ComparisonSettings} can be {@link #merge(ComparisonSettings) merged} with another
24   * instance, which will result in the other instance 'single' fields overriding this instance's corresponding fields,
25   * unless they were not set on the other instance at all. Collection fields are merged by combining collections from
26   * both merged instances.
27   *
28   * <p/>
29   * A family of short-hand methods is also available on this class (many of them starting with a {@code with} prefix) to
30   * facilitate creating a new instance of settings overriding, or adding just one specific field from the original
31   * instance. Those work in essence as if this instance was {@link #merge(ComparisonSettings) merged} with another
32   * instance of settings that had just that one particular field set.
33   *
34   * @since 2.3
35   */
36  @Immutable
37  @ExperimentalApi
38  public final class ComparisonSettings
39  {
40      private final Set<Resolution> resolutions;
41  
42      private final File baselineDir;
43      private final Boolean reportingEnabled;
44      private final File reportingDir;
45  
46      private final Boolean ignoreSingleLineDifferences;
47      private final Boolean refreshAfterResize;
48  
49      private final Iterable<PagePart> ignoredParts;
50      private final Iterable<Replacement> replacements;
51  
52      private ComparisonSettings()
53      {
54          this(new Builder());
55      }
56  
57      private ComparisonSettings(Builder builder)
58      {
59          resolutions = builder.resolutions.build();
60  
61          baselineDir = builder.baselineDir;
62          reportingEnabled = builder.reportingEnabled;
63          reportingDir = builder.reportingDir;
64  
65          ignoreSingleLineDifferences = builder.ignoreSingleLineDifferences;
66          refreshAfterResize = builder.refreshAfterResize;
67  
68          ignoredParts = builder.ignoredParts.build();
69          replacements = builder.replacements.build();
70      }
71  
72      /**
73       * Creates a new empty instance of settings. All simple fields are {@code null} (not set) and the collection
74       * fields are empty collections.
75       *
76       * @return new empty instance of {@code ComparisonSettings}.
77       */
78      @Nonnull
79      public static ComparisonSettings emptySettings()
80      {
81          return new ComparisonSettings();
82      }
83  
84      @Nonnull
85      public Set<Resolution> getResolutions()
86      {
87          return resolutions;
88      }
89  
90      @Nullable
91      public File getBaselineDirectory()
92      {
93          return baselineDir;
94      }
95  
96      public boolean isReportingEnabled()
97      {
98          return reportingEnabled != null && reportingEnabled;
99      }
100 
101     @Nullable
102     public File getReportingDirectory()
103     {
104         return reportingDir;
105     }
106 
107     public boolean isIgnoreSingleLineDifferences()
108     {
109         return ignoreSingleLineDifferences != null && ignoreSingleLineDifferences;
110     }
111 
112     public boolean isRefreshAfterResize()
113     {
114         return refreshAfterResize != null && refreshAfterResize;
115     }
116 
117     @Nonnull
118     public Iterable<PagePart> getIgnoredParts()
119     {
120         return ignoredParts;
121     }
122 
123     @Nonnull
124     public Iterable<Replacement> getReplacements()
125     {
126         return replacements;
127     }
128 
129     @Nonnull
130     public ComparisonSettings merge(ComparisonSettings that)
131     {
132         return new Builder(this).merge(that).build();
133     }
134 
135     @Nonnull
136     public ComparisonSettings withResolution(@Nonnull Resolution resolution)
137     {
138         return new Builder(this).resolution(resolution).build();
139     }
140 
141     @Nonnull
142     public ComparisonSettings withResolutions(@Nonnull Resolution first, @Nonnull Resolution... more)
143     {
144         return new Builder(this).resolutions(first, more).build();
145     }
146 
147     @Nonnull
148     public ComparisonSettings withBaselineDirectory(@Nonnull File baselineDirectory)
149     {
150         return new Builder(this).baselineDirectory(baselineDirectory).build();
151     }
152 
153     @Nonnull
154     public ComparisonSettings withReportingEnabled(@Nonnull File value)
155     {
156         return new Builder(this).enableReporting(value).build();
157     }
158 
159     @Nonnull
160     public ComparisonSettings withReportingDisabled()
161     {
162         return new Builder(this).disableReporting().build();
163     }
164 
165     @Nonnull
166     public ComparisonSettings ignoringSingleLineDifferences(boolean value)
167     {
168         return new Builder(this).ignoreSingleLineDifferences(value).build();
169     }
170 
171     @Nonnull
172     public ComparisonSettings refreshingAfterResize(boolean refreshAfterResize)
173     {
174         return new Builder(this).refreshAfterResize(refreshAfterResize).build();
175     }
176 
177     @Nonnull
178     public ComparisonSettings ignoringPart(@Nonnull PagePart part) {
179         return new Builder(this).ignorePart(part).build();
180     }
181 
182     @Nonnull
183     public ComparisonSettings withReplacement(@Nonnull Replacement replacement) {
184         return new Builder(this).replacement(replacement).build();
185     }
186 
187     private static final class Builder
188     {
189         private final ImmutableSortedSet.Builder<Resolution> resolutions = ImmutableSortedSet.naturalOrder();
190 
191         private File baselineDir;
192         private Boolean reportingEnabled;
193         private File reportingDir;
194 
195         private Boolean ignoreSingleLineDifferences;
196         private Boolean refreshAfterResize;
197 
198         private ImmutableList.Builder<PagePart> ignoredParts = ImmutableList.builder();
199         private ImmutableList.Builder<Replacement> replacements = ImmutableList.builder();
200 
201         Builder()
202         {
203         }
204 
205         Builder(@Nonnull ComparisonSettings settings)
206         {
207             merge(settings);
208         }
209 
210         Builder merge(@Nonnull ComparisonSettings settings)
211         {
212             checkNotNull(settings, "settings");
213             resolutions.addAll(settings.resolutions);
214 
215             baselineDir = settings.baselineDir != null ? settings.baselineDir : baselineDir;
216             reportingEnabled = settings.reportingEnabled != null ? settings.reportingEnabled : reportingEnabled;
217             reportingDir = settings.reportingEnabled != null ? settings.reportingDir : reportingDir;
218 
219             ignoreSingleLineDifferences = settings.ignoreSingleLineDifferences != null
220                     ? settings.ignoreSingleLineDifferences : ignoreSingleLineDifferences;
221             refreshAfterResize = settings.refreshAfterResize != null ? settings.refreshAfterResize : refreshAfterResize;
222 
223             ignoredParts.addAll(settings.ignoredParts);
224             replacements.addAll(settings.replacements);
225             return this;
226         }
227 
228         @Nonnull
229         Builder resolution(@Nonnull Resolution resolution)
230         {
231             resolutions.add(resolution);
232             return this;
233         }
234 
235         @Nonnull
236         Builder resolutions(@Nonnull Resolution resolution, @Nonnull Resolution... more)
237         {
238             resolutions.add(resolution).addAll(asList(more));
239             return this;
240         }
241 
242         @Nonnull
243         public Builder baselineDirectory(@Nonnull File value)
244         {
245             this.baselineDir = checkNotNull(value, "baselineDirectory");
246             return this;
247         }
248 
249         @Nonnull
250         Builder enableReporting(@Nonnull File value)
251         {
252             checkNotNull(value, "reportingDir");
253             reportingEnabled = true;
254             reportingDir = value;
255             return this;
256         }
257 
258         @Nonnull
259         Builder disableReporting()
260         {
261             reportingEnabled = false;
262             reportingDir = null;
263             return this;
264         }
265 
266         @Nonnull
267         Builder ignoreSingleLineDifferences(boolean value)
268         {
269             ignoreSingleLineDifferences = value;
270             return this;
271         }
272 
273         @Nonnull
274         Builder refreshAfterResize(boolean value)
275         {
276             refreshAfterResize = value;
277             return this;
278         }
279 
280         @Nonnull
281         Builder ignorePart(@Nonnull PagePart part)
282         {
283             ignoredParts.add(part);
284             return this;
285         }
286 
287         @Nonnull
288         Builder ignoreParts(@Nonnull PagePart first, @Nonnull PagePart... more)
289         {
290             ignoredParts.add(first).addAll(asList(more));
291             return this;
292         }
293 
294         @Nonnull
295         Builder replacement(@Nonnull Replacement replacement)
296         {
297             replacements.add(replacement);
298             return this;
299         }
300 
301         @Nonnull
302         Builder replacements(@Nonnull Replacement first, @Nonnull Replacement... more)
303         {
304             replacements.add(first).addAll(asList(more));
305             return this;
306         }
307 
308         public ComparisonSettings build()
309         {
310             return new ComparisonSettings(this);
311         }
312     }
313 }