code: /*
  * Copyright 2014 Basis Technology Corp.
  *
  * 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.basistech.tclre;
  
  import org.junit.Test;
  
  import static com.basistech.tclre.Utils.Matches.matches;
  import static org.hamcrest.CoreMatchers.not;
  import static org.hamcrest.MatcherAssert.assertThat;
  import static org.junit.Assert.assertTrue;
  
  /**
   * Test for the lexer.
   */
  public class LexTest extends Utils {
      private void assertCatchCompileTime(String regex) {
          try {
              HsrePattern.compile(regex, PatternFlags.ADVANCED);
              assertTrue(false);  /* should throw! */
          } catch (RegexException ree) {
              assertTrue(true);
          }
      }
  
      //CHECKSTYLE:OFF
      @Test
      public void testLex() throws Exception {
          RePattern exp = HsrePattern.compile("a.*+[bc]d$+", PatternFlags.QUOTE);
          assertThat("a.*+[bc]d$+", matches(exp));
          assertThat("a.*+[ef]d$+", not(matches(exp)));
          assertCatchCompileTime("***?kaboom");
          assertCatchCompileTime("***qkaboum");
          assertCatchCompileTime("(?z)");
  
          HsrePattern.compile("(?b)", PatternFlags.ADVANCED);
          exp = HsrePattern.compile("(?i)aaBB", PatternFlags.ADVANCED);
          assertThat("aAbB", matches(exp));
          exp = HsrePattern.compile("(?c)aaBB", PatternFlags.ADVANCED);
          assertThat("aaBB", matches(exp));
          assertThat("aAbB", not(matches(exp)));
          exp = HsrePattern.compile("a\\nb", PatternFlags.ADVANCED);
          assertThat("a\nb", matches(exp));
          exp = HsrePattern.compile("(?e)a\\nb", PatternFlags.ADVANCED);
          assertThat("a\nb", not(matches(exp))); /* ERE mode */
          exp = HsrePattern.compile("(?n)^bcd$", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", matches(exp));
          exp = HsrePattern.compile("(?s)^bcd$", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", not(matches(exp)));
          exp = HsrePattern.compile("(?s)^01.*fg$", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", matches(exp));
          exp = HsrePattern.compile("(?p)^01.*fg$", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", not(matches(exp)));
          exp = HsrePattern.compile("(?p)^.*\n.*\n.*fg$", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", matches(exp));
          exp = HsrePattern.compile("(?q)^01.*fg$", PatternFlags.ADVANCED);
          assertThat("^01.*fg$", matches(exp)); /* quote */
          exp = HsrePattern.compile("(?x)abc #bar baz", PatternFlags.ADVANCED);
          assertThat("abcbarbaz", matches(exp));
          exp = HsrePattern.compile("(?t)abc #bar baz", PatternFlags.ADVANCED);
          assertThat("abcbarbaz", not(matches(exp)));
          exp = HsrePattern.compile("(?w).*", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", matches(exp));
          exp = HsrePattern.compile("(?w)^.*fg$", PatternFlags.ADVANCED);
          assertThat("01a\nbcd\nefg", matches(exp));
          assertCatchCompileTime("(?p");
          exp = HsrePattern.compile("[[.number-sign.]]");
          assertThat("#", matches(exp));
          assertThat("n", not(matches(exp)));
          exp = HsrePattern.compile("a{3,5}?", PatternFlags.ADVANCED); /*non-greedy*/
          assertThat("aaaa", matches(exp));
          assertCatchCompileTime("a[3,4");
          assertCatchCompileTime("a{3,4");
          assertCatchCompileTime("[[:digit:}");
          exp = HsrePattern.compile("a\\x123q", PatternFlags.ADVANCED);
          assertThat("a\u0123q", matches(exp));
  
          assertCatchCompileTime("a[\\");
          exp = HsrePattern.compile("a[\\d]", PatternFlags.ADVANCED);
          assertThat("a3", matches(exp));
          assertThat("ab", not(matches(exp)));
          exp = HsrePattern.compile("a[\\w]", PatternFlags.ADVANCED);
          assertThat("aQ", matches(exp));
          assertThat("a$", not(matches(exp)));
          assertCatchCompileTime("a[[");
          exp = HsrePattern.compile("a\\{3,5\\}", PatternFlags.BASIC);
          assertThat("aaaa", matches(exp));
          assertThat("aa", not(matches(exp)));
          exp = HsrePattern.compile("a[\\]b", PatternFlags.BASIC);
          assertThat("a\\b", matches(exp));
          assertCatchCompileTime("a{3,q}");
          assertCatchCompileTime("a[\\q]");
          HsrePattern.compile("[[q]]", PatternFlags.ADVANCED);
          /* not clear what this (above) means, but code special-cases it. */
          exp = HsrePattern.compile("a.+?b", PatternFlags.ADVANCED);
          assertThat("acwwdcdbwfefwb", matches(exp)); /* won't say which*/
          assertThat("ab", not(matches(exp)));
          exp = HsrePattern.compile("a.??b", PatternFlags.ADVANCED); /* meaning.?? */
          assertThat("ab", matches(exp)); /* won't say which*/
          exp = HsrePattern.compile("a{b", PatternFlags.EXPANDED); /* meaning.?? */
          assertThat("a{b", matches(exp));
          assertThat("a[b", not(matches(exp)));
          exp = HsrePattern.compile("a(?#foo)b", PatternFlags.ADVANCED);
          assertThat("ab", matches(exp));
          exp = HsrePattern.compile("a(?!foo)b", PatternFlags.ADVANCED);
          assertThat("ab", matches(exp));
          assertCatchCompileTime("a(?&)b");
          exp = HsrePattern.compile("[\\r][\\b][\\f][\\a][\\e][\\v][\\t]", PatternFlags.ADVANCED);
          assertThat("\r\b\f\007\033\u000b\t", matches(exp));
  
          assertCatchCompileTime("\\c");
          assertCatchCompileTime("\\");
          exp = HsrePattern.compile("\\cC\\B\\w\\D\\S\\W", PatternFlags.ADVANCED);
          assertThat("\u0003\\_!$@", matches(exp));
  
          exp = HsrePattern.compile("[\\uABCD][\\uEF89][\\U0001039F]?", PatternFlags.ADVANCED);
          assertThat("\uABCD\uEF89", matches(exp));
          HsrePattern.compile(".*[[:<:]].*[[:>:]].*", PatternFlags.ADVANCED);
          /* TODO:This works against C++, but doesn't work here. It's deprecated, though. */
          // assertThat("^%*&^AbulBakr@#$#@$", matches(exp));
  
          exp = HsrePattern.compile("*a*b$a$", PatternFlags.BASIC);
          assertThat("*aaab$a", matches(exp));
          exp = HsrePattern.compile("^q^b$c$", PatternFlags.BASIC);
          assertThat("q^b$c", matches(exp));
          assertCatchCompileTime("(?b)\\");
          exp = HsrePattern.compile("\\(a|b\\)", PatternFlags.BASIC);
          assertThat("a|b", matches(exp, new String[]{"a|b"}));
          exp = HsrePattern.compile("[ab]", PatternFlags.BASIC);
          assertThat("a", matches(exp));
          exp = HsrePattern.compile("\\(.*\\)\\<\\(.*\\)\\>\\(.*\\)", PatternFlags.BASIC);
          /* Amazingly, this works in this form in BASIC */
          assertThat("^%*&^AbulBakr@#$#@$", matches(exp, new String[]{"^%*&^", "AbulBakr", "@#$#@$"}));
      }
  }
  