    1   /***
    2    *
    3    * Copyright 2004 Protique Ltd
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    * http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   **/
    18  package org.codehaus.activemq.selector;
    19
    20  import junit.framework.TestCase;
    21  import org.codehaus.activemq.filter.Filter;
    22  import org.codehaus.activemq.message.ActiveMQMessage;
    23  import org.codehaus.activemq.message.ActiveMQTopic;
    24
    25  import javax.jms.Destination;
    26  import javax.jms.InvalidSelectorException;
    27  import javax.jms.JMSException;
    28  import javax.jms.Message;
    29
    30  /***
    31   * @version $Revision: 1.13 $
    32   */
    33  public class SelectorTest extends TestCase {
    34
    35      public void testBasicSelectors() throws Exception {
    36          Message message = createMessage();
    37
    38          assertSelector(message, "name = 'James'", true);
    39          assertSelector(message, "rank > 100", true);
    40          assertSelector(message, "rank >= 123", true);
    41          assertSelector(message, "rank >= 124", false);
    42      }
    43
    44      public void testAndSelectors() throws Exception {
    45          Message message = createMessage();
    46
    47          assertSelector(message, "name = 'James' and rank < 200", true);
    48          assertSelector(message, "name = 'James' and rank > 200", false);
    49          assertSelector(message, "name = 'Foo' and rank < 200", false);
    50          assertSelector(message, "unknown = 'Foo' and anotherUnknown < 200", false);
    51      }
    52
    53      public void testOrSelectors() throws Exception {
    54          Message message = createMessage();
    55
    56          assertSelector(message, "name = 'James' or rank < 200", true);
    57          assertSelector(message, "name = 'James' or rank > 200", true);
    58          assertSelector(message, "name = 'Foo' or rank < 200", true);
    59          assertSelector(message, "name = 'Foo' or rank > 200", false);
    60          assertSelector(message, "unknown = 'Foo' or anotherUnknown < 200", false);
    61      }
    62
    63      public void testPlus() throws Exception {
    64          Message message = createMessage();
    65
    66          assertSelector(message, "rank + 2 = 125", true);
    67          assertSelector(message, "(rank + 2) = 125", true);
    68          assertSelector(message, "125 = (rank + 2)", true);
    69          assertSelector(message, "rank + version = 125", true);
    70          assertSelector(message, "rank + 2 < 124", false);
    71          assertSelector(message, "name + '!' = 'James!'", true);
    72      }
    73
    74      public void testMinus() throws Exception {
    75          Message message = createMessage();
    76
    77          assertSelector(message, "rank - 2 = 121", true);
    78          assertSelector(message, "rank - version = 121", true);
    79          assertSelector(message, "rank - 2 > 122", false);
    80      }
    81
    82      public void testMultiply() throws Exception {
    83          Message message = createMessage();
    84
    85          assertSelector(message, "rank * 2 = 246", true);
    86          assertSelector(message, "rank * version = 246", true);
    87          assertSelector(message, "rank * 2 < 130", false);
    88      }
    89
    90      public void testDivide() throws Exception {
    91          Message message = createMessage();
    92
    93          assertSelector(message, "rank / version = 61.5", true);
    94          assertSelector(message, "rank / 3 > 100.0", false);
    95          assertSelector(message, "rank / 3 > 100", false);
    96          assertSelector(message, "version / 2 = 1", true);
    97
    98      }
    99
    100     public void testBetween() throws Exception {
    101         Message message = createMessage();
    102
    103         assertSelector(message, "rank between 100 and 150", true);
    104         assertSelector(message, "rank between 10 and 120", false);
    105     }
    106
    107     public void testIn() throws Exception {
    108         Message message = createMessage();
    109
    110         assertSelector(message, "name in ('James', 'Bob', 'Gromit')", true);
    111         assertSelector(message, "name in ('Bob', 'James', 'Gromit')", true);
    112         assertSelector(message, "name in ('Gromit', 'Bob', 'James')", true);
    113
    114         assertSelector(message, "name in ('Gromit', 'Bob', 'Cheddar')", false);
    115         assertSelector(message, "name not in ('Gromit', 'Bob', 'Cheddar')", true);
    116     }
    117
    118     public void testIsNull() throws Exception {
    119         Message message = createMessage();
    120
    121         assertSelector(message, "dummy is null", true);
    122         assertSelector(message, "dummy is not null", false);
    123         assertSelector(message, "name is not null", true);
    124         assertSelector(message, "name is null", false);
    125     }
    126
    127     public void testFloatComparisons() throws Exception {
    128         Message message = createMessage();
    129
    130         // JMS 1.1 Section 3.8.1.1 : Approximate literals use the Java floating-point literal syntax.
    131         // We will use the java varible x to demo valid floating point syntaxs.
    132         double x;
    133
    134         // test decimals like x.x
    135         x = 1.0;
    136         x = -1.1;
    137         x = 1.0E1;
    138         x = 1.1E1;
    139         x = -1.1E1;
    140         assertSelector(message, "1.0 < 1.1", true);
    141         assertSelector(message, "-1.1 < 1.0", true);
    142         assertSelector(message, "1.0E1 < 1.1E1", true);
    143         assertSelector(message, "-1.1E1 < 1.0E1", true);
    144
    145         // test decimals like x.
    146         x = 1.;
    147         x = 1.E1;
    148         assertSelector(message, "1. < 1.1", true);
    149         assertSelector(message, "-1.1 < 1.", true);
    150         assertSelector(message, "1.E1 < 1.1E1", true);
    151         assertSelector(message, "-1.1E1 < 1.E1", true);
    152
    153         // test decimals like .x
    154         x = .5;
    155         x = -.5;
    156         x = .5E1;
    157         assertSelector(message, ".1 < .5", true);
    158         assertSelector(message, "-.5 < .1", true);
    159         assertSelector(message, ".1E1 < .5E1", true);
    160         assertSelector(message, "-.5E1 < .1E1", true);
    161
    162         // test exponents
    163         x = 4E10;
    164         x = -4E10;
    165         x = 5E+10;
    166         x = 5E-10;
    167         assertSelector(message, "4E10 < 5E10", true);
    168         assertSelector(message, "5E8 < 5E10", true);
    169         assertSelector(message, "-4E10 < 2E10", true);
    170         assertSelector(message, "-5E8 < 2E2", true);
    171         assertSelector(message, "4E+10 < 5E+10", true);
    172         assertSelector(message, "4E-10 < 5E-10", true);
    173     }
    174
    175     public void testStringQuoteParsing() throws Exception {
    176         Message message = createMessage();
    177         assertSelector(message, "quote = '''In God We Trust'''", true);
    178     }
    179
    180     public void testLikeComparisons() throws Exception {
    181         Message message = createMessage();
    182
    183         assertSelector(message, "quote LIKE '''In G_d We Trust'''", true);
    184         assertSelector(message, "quote LIKE '''In Gd_ We Trust'''", false);
    185         assertSelector(message, "quote NOT LIKE '''In G_d We Trust'''", false);
    186         assertSelector(message, "quote NOT LIKE '''In Gd_ We Trust'''", true);
    187
    188         assertSelector(message, "foo LIKE '%oo'", true);
    189         assertSelector(message, "foo LIKE '%ar'", false);
    190         assertSelector(message, "foo NOT LIKE '%oo'", false);
    191         assertSelector(message, "foo NOT LIKE '%ar'", true);
    192
    193         assertSelector(message, "foo LIKE '!_%' ESCAPE '!'", true);
    194         assertSelector(message, "quote LIKE '!_%' ESCAPE '!'", false);
    195         assertSelector(message, "foo NOT LIKE '!_%' ESCAPE '!'", false);
    196         assertSelector(message, "quote NOT LIKE '!_%' ESCAPE '!'", true);
    197
    198         assertSelector(message, "punctuation LIKE '!#$&()*+,-./:;<=>?@[//]^`{|}~'", true);
    199     }
    200
    201     public void testInvalidSelector() throws Exception {
    202         Message message = createMessage();
    203         assertInvalidSelector(message, "3+5");
    204         assertInvalidSelector(message, "True AND 3+5");
    205         assertInvalidSelector(message, "=TEST 'test'");
    206     }
    207
    208     protected Message createMessage() throws JMSException {
    209         Message message = createMessage("FOO.BAR");
    210         message.setObjectProperty("name", "James");
    211         message.setObjectProperty("location", "London");
    212         message.setIntProperty("rank", 123);
    213         message.setIntProperty("version", 2);
    214         message.setStringProperty("quote", "'In God We Trust'");
    215         message.setStringProperty("foo", "_foo");
    216         message.setStringProperty("punctuation", "!#$&()*+,-./:;<=>?@[//]^`{|}~");
    217
    218         return message;
    219     }
    220
    221
    222     protected void assertInvalidSelector(Message message, String text) throws JMSException {
    223         try {
    224             Filter selector = new SelectorParser().parse(text);
    225             fail("Created a valid selector");
    226         }
    227         catch (InvalidSelectorException e) {
    228         }
    229     }
    230
    231     protected void assertSelector(Message message, String text, boolean expected) throws JMSException {
    232         Filter selector = new SelectorParser().parse(text);
    233         assertTrue("Created a valid selector", selector != null);
    234
    235         boolean value = selector.matches(message);
    236
    237         assertEquals("Selector for: " + text, expected, value);
    238     }
    239
    240     protected Message createMessage(String subject) {
    241         ActiveMQMessage message = new ActiveMQMessage();
    242         message.setJMSDestination(createDestination(subject));
    243         return message;
    244     }
    245
    246     protected Destination createDestination(String subject) {
    247         return new ActiveMQTopic(subject);
    248     }
    249 }