1/**
2 * Copyright (C) 2010 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.inject.servlet;
18
19import static com.google.inject.servlet.UriPatternType.REGEX;
20import static com.google.inject.servlet.UriPatternType.SERVLET;
21
22import com.google.common.collect.ImmutableList;
23import com.google.common.collect.ImmutableMap;
24import com.google.inject.Binding;
25import com.google.inject.Guice;
26import com.google.inject.Injector;
27import com.google.inject.Key;
28import com.google.inject.name.Names;
29import com.google.inject.servlet.ServletSpiVisitor.Params;
30import com.google.inject.spi.Element;
31import com.google.inject.spi.Elements;
32
33import junit.framework.TestCase;
34
35import java.util.Iterator;
36import java.util.List;
37
38/**
39 * A very basic test that servletmodule works with bindings.
40 *
41 * @author sameb@google.com (Sam Berlin)
42 */
43public class ExtensionSpiTest extends TestCase {
44
45  private DummyFilterImpl dummyFilter1 = new DummyFilterImpl();
46  private DummyFilterImpl dummyFilter2 = new DummyFilterImpl();
47  private DummyFilterImpl dummyFilter3 = new DummyFilterImpl();
48  private DummyFilterImpl dummyFilter4 = new DummyFilterImpl();
49
50  private DummyServlet dummyServlet1 = new DummyServlet();
51  private DummyServlet dummyServlet2 = new DummyServlet();
52  private DummyServlet dummyServlet3 = new DummyServlet();
53  private DummyServlet dummyServlet4 = new DummyServlet();
54
55  public final void testSpiOnElements() {
56    ServletSpiVisitor visitor = new ServletSpiVisitor(false);
57    int count = 0;
58    for(Element element : Elements.getElements(new Module())) {
59      if(element instanceof Binding) {
60        assertEquals(count++, ((Binding)element).acceptTargetVisitor(visitor));
61      }
62    }
63    validateVisitor(visitor);
64  }
65
66  public final void testSpiOnInjector() {
67    ServletSpiVisitor visitor = new ServletSpiVisitor(true);
68    int count = 0;
69    Injector injector = Guice.createInjector(new Module());
70    for(Binding binding : injector.getBindings().values()) {
71      assertEquals(count++, binding.acceptTargetVisitor(visitor));
72    }
73    validateVisitor(visitor);
74  }
75
76  private void validateVisitor(ServletSpiVisitor visitor) {
77    assertEquals(48, visitor.currentCount - visitor.otherCount);
78
79    // This is the expected param list, in order..
80    List<Params> expected = ImmutableList.of(
81        new Params("/class", Key.get(DummyFilterImpl.class), ImmutableMap.of(), SERVLET),
82        new Params("/class/2", Key.get(DummyFilterImpl.class), ImmutableMap.of(), SERVLET),
83        new Params("/key", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
84        new Params("/key/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
85        new Params("/instance", dummyFilter1, ImmutableMap.of(), SERVLET),
86        new Params("/instance/2", dummyFilter1, ImmutableMap.of(), SERVLET),
87        new Params("/class/keyvalues", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), SERVLET),
88        new Params("/class/keyvalues/2", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), SERVLET),
89        new Params("/key/keyvalues", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
90        new Params("/key/keyvalues/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
91        new Params("/instance/keyvalues", dummyFilter2, ImmutableMap.of("key", "value"), SERVLET),
92        new Params("/instance/keyvalues/2", dummyFilter2, ImmutableMap.of("key", "value"), SERVLET),
93
94        new Params("/class[0-9]", Key.get(DummyFilterImpl.class), ImmutableMap.of(), REGEX),
95        new Params("/class[0-9]/2", Key.get(DummyFilterImpl.class), ImmutableMap.of(), REGEX),
96        new Params("/key[0-9]", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), REGEX),
97        new Params("/key[0-9]/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of(), REGEX),
98        new Params("/instance[0-9]", dummyFilter3, ImmutableMap.of(), REGEX),
99        new Params("/instance[0-9]/2", dummyFilter3, ImmutableMap.of(), REGEX),
100        new Params("/class[0-9]/keyvalues", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), REGEX),
101        new Params("/class[0-9]/keyvalues/2", Key.get(DummyFilterImpl.class), ImmutableMap.of("key", "value"), REGEX),
102        new Params("/key[0-9]/keyvalues", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
103        new Params("/key[0-9]/keyvalues/2", Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
104        new Params("/instance[0-9]/keyvalues", dummyFilter4, ImmutableMap.of("key", "value"), REGEX),
105        new Params("/instance[0-9]/keyvalues/2", dummyFilter4, ImmutableMap.of("key", "value"), REGEX),
106
107        new Params("/class", Key.get(DummyServlet.class), ImmutableMap.of(), SERVLET),
108        new Params("/class/2", Key.get(DummyServlet.class), ImmutableMap.of(), SERVLET),
109        new Params("/key", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
110        new Params("/key/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), SERVLET),
111        new Params("/instance", dummyServlet1, ImmutableMap.of(), SERVLET),
112        new Params("/instance/2", dummyServlet1, ImmutableMap.of(), SERVLET),
113        new Params("/class/keyvalues", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), SERVLET),
114        new Params("/class/keyvalues/2", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), SERVLET),
115        new Params("/key/keyvalues", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
116        new Params("/key/keyvalues/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), SERVLET),
117        new Params("/instance/keyvalues", dummyServlet2, ImmutableMap.of("key", "value"), SERVLET),
118        new Params("/instance/keyvalues/2", dummyServlet2, ImmutableMap.of("key", "value"), SERVLET),
119
120        new Params("/class[0-9]", Key.get(DummyServlet.class), ImmutableMap.of(), REGEX),
121        new Params("/class[0-9]/2", Key.get(DummyServlet.class), ImmutableMap.of(), REGEX),
122        new Params("/key[0-9]", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), REGEX),
123        new Params("/key[0-9]/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of(), REGEX),
124        new Params("/instance[0-9]", dummyServlet3, ImmutableMap.of(), REGEX),
125        new Params("/instance[0-9]/2", dummyServlet3, ImmutableMap.of(), REGEX),
126        new Params("/class[0-9]/keyvalues", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), REGEX),
127        new Params("/class[0-9]/keyvalues/2", Key.get(DummyServlet.class), ImmutableMap.of("key", "value"), REGEX),
128        new Params("/key[0-9]/keyvalues", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
129        new Params("/key[0-9]/keyvalues/2", Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"), REGEX),
130        new Params("/instance[0-9]/keyvalues", dummyServlet4, ImmutableMap.of("key", "value"), REGEX),
131        new Params("/instance[0-9]/keyvalues/2", dummyServlet4, ImmutableMap.of("key", "value"), REGEX)
132    );
133
134    assertEquals(expected.size(), visitor.actual.size());
135    Iterator<Params> actualIterator = visitor.actual.iterator();
136    int i = 0;
137    for(Params param : expected) {
138      assertEquals("wrong " + i++ + "th param", param, actualIterator.next());
139    }
140  }
141
142  private class Module extends ServletModule {
143    @Override
144    protected void configureServlets() {
145      binder().requireExplicitBindings();
146
147      filter("/class", "/class/2").through(DummyFilterImpl.class);
148      filter("/key", "/key/2").through(
149          Key.get(DummyFilterImpl.class, Names.named("foo")));
150      filter("/instance", "/instance/2").through(dummyFilter1);
151      filter("/class/keyvalues", "/class/keyvalues/2").through(
152          DummyFilterImpl.class, ImmutableMap.of("key", "value"));
153      filter("/key/keyvalues", "/key/keyvalues/2").through(
154          Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"));
155      filter("/instance/keyvalues", "/instance/keyvalues/2").through(
156          dummyFilter2, ImmutableMap.of("key", "value"));
157
158      filterRegex("/class[0-9]", "/class[0-9]/2").through(DummyFilterImpl.class);
159      filterRegex("/key[0-9]", "/key[0-9]/2").through(
160          Key.get(DummyFilterImpl.class, Names.named("foo")));
161      filterRegex("/instance[0-9]", "/instance[0-9]/2").through(dummyFilter3);
162      filterRegex("/class[0-9]/keyvalues", "/class[0-9]/keyvalues/2").through(
163          DummyFilterImpl.class, ImmutableMap.of("key", "value"));
164      filterRegex("/key[0-9]/keyvalues", "/key[0-9]/keyvalues/2").through(
165          Key.get(DummyFilterImpl.class, Names.named("foo")), ImmutableMap.of("key", "value"));
166      filterRegex("/instance[0-9]/keyvalues", "/instance[0-9]/keyvalues/2").through(
167          dummyFilter4, ImmutableMap.of("key", "value"));
168
169      serve("/class", "/class/2").with(DummyServlet.class);
170      serve("/key", "/key/2").with(
171          Key.get(DummyServlet.class, Names.named("foo")));
172      serve("/instance", "/instance/2").with(dummyServlet1);
173      serve("/class/keyvalues", "/class/keyvalues/2").with(
174          DummyServlet.class, ImmutableMap.of("key", "value"));
175      serve("/key/keyvalues", "/key/keyvalues/2").with(
176          Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"));
177      serve("/instance/keyvalues", "/instance/keyvalues/2").with(
178          dummyServlet2, ImmutableMap.of("key", "value"));
179
180      serveRegex("/class[0-9]", "/class[0-9]/2").with(DummyServlet.class);
181      serveRegex("/key[0-9]", "/key[0-9]/2").with(
182          Key.get(DummyServlet.class, Names.named("foo")));
183      serveRegex("/instance[0-9]", "/instance[0-9]/2").with(dummyServlet3);
184      serveRegex("/class[0-9]/keyvalues", "/class[0-9]/keyvalues/2").with(
185          DummyServlet.class, ImmutableMap.of("key", "value"));
186      serveRegex("/key[0-9]/keyvalues", "/key[0-9]/keyvalues/2").with(
187          Key.get(DummyServlet.class, Names.named("foo")), ImmutableMap.of("key", "value"));
188      serveRegex("/instance[0-9]/keyvalues", "/instance[0-9]/keyvalues/2").with(
189          dummyServlet4, ImmutableMap.of("key", "value"));
190    }
191  }
192}
193