aboutsummaryrefslogtreecommitdiff
path: root/extensions/re2j/src/main/java/com/google/common/truth/extensions/re2j/Re2jSubjects.java
blob: 67b1ed81c5c689e66c25d149bee2ca0d928d5636 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Copyright (c) 2015 Google, Inc.
 *
 * 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.google.common.truth.extensions.re2j;

import com.google.common.annotations.GwtIncompatible;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.Subject;
import com.google.re2j.Pattern;

/**
 * Truth subjects for re2j regular expressions.
 *
 * <p>Truth natively provides subjects for dealing with {@code java.util.regex} based regular
 * expressions. This class is intended to provide {@code com.google.re2j} analogues to those
 * methods.
 */
public final class Re2jSubjects {
  /**
   * Returns a subject factory for {@link String} subjects which you can use to assert things about
   * {@link com.google.re2j.Pattern} regexes.
   *
   * <p>This subject does not replace Truth's built-in {@link com.google.common.truth.StringSubject}
   * but instead provides only the methods needed to deal with regular expressions.
   *
   * @see com.google.common.truth.StringSubject
   */
  public static Subject.Factory<Re2jStringSubject, String> re2jString() {
    return Re2jStringSubject.FACTORY;
  }

  /**
   * Subject for {@link String} subjects which you can use to assert things about {@link
   * com.google.re2j.Pattern} regexes.
   *
   * @see #re2jString
   */
  public static final class Re2jStringSubject extends Subject {
    private static final Subject.Factory<Re2jStringSubject, String> FACTORY =
        new Subject.Factory<Re2jStringSubject, String>() {
          @Override
          public Re2jStringSubject createSubject(FailureMetadata failureMetadata, String target) {
            return new Re2jStringSubject(failureMetadata, target);
          }
        };

    private final String actual;

    private Re2jStringSubject(FailureMetadata failureMetadata, String subject) {
      super(failureMetadata, subject);
      this.actual = subject;
    }

    @Override
    protected String actualCustomStringRepresentation() {
      return quote(actual);
    }

    /** Fails if the string does not match the given regex. */
    public void matches(String regex) {
      if (!Pattern.matches(regex, actual)) {
        failWithActual("expected to match ", regex);
      }
    }

    /** Fails if the string does not match the given regex. */
    @GwtIncompatible("com.google.re2j.Pattern")
    public void matches(Pattern regex) {
      if (!regex.matcher(actual).matches()) {
        failWithActual("expected to match ", regex);
      }
    }

    /** Fails if the string matches the given regex. */
    public void doesNotMatch(String regex) {
      if (Pattern.matches(regex, actual)) {
        failWithActual("expected to fail to match", regex);
      }
    }

    /** Fails if the string matches the given regex. */
    @GwtIncompatible("com.google.re2j.Pattern")
    public void doesNotMatch(Pattern regex) {
      if (regex.matcher(actual).matches()) {
        failWithActual("expected to fail to match", regex);
      }
    }

    /** Fails if the string does not contain a match on the given regex. */
    @GwtIncompatible("com.google.re2j.Pattern")
    public void containsMatch(Pattern pattern) {
      if (!pattern.matcher(actual).find()) {
        failWithActual("expected to contain a match for", pattern);
      }
    }

    /** Fails if the string does not contain a match on the given regex. */
    public void containsMatch(String regex) {
      if (!doContainsMatch(actual, regex)) {
        failWithActual("expected to contain a match for", regex);
      }
    }

    /** Fails if the string contains a match on the given regex. */
    @GwtIncompatible("com.google.re2j.Pattern")
    public void doesNotContainMatch(Pattern pattern) {
      if (pattern.matcher(actual).find()) {
        failWithActual("expected not to contain a match for", pattern);
      }
    }

    /** Fails if the string contains a match on the given regex. */
    public void doesNotContainMatch(String regex) {
      if (doContainsMatch(actual, regex)) {
        failWithActual("expected not to contain a match for", regex);
      }
    }

    private static String quote(CharSequence toBeWrapped) {
      return "\"" + toBeWrapped + "\"";
    }

    private static boolean doContainsMatch(String subject, String regex) {
      return Pattern.compile(regex).matcher(subject).find();
    }
  }

  private Re2jSubjects() {}
}