1/**
2 * Copyright (C) 2010 the original author or authors.
3 * See the notice.md file distributed with this work for additional
4 * information regarding copyright ownership.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19package com.beust.jcommander.command;
20
21import com.beust.jcommander.JCommander;
22import com.beust.jcommander.ParameterException;
23import org.testng.Assert;
24import org.testng.annotations.Test;
25
26import java.util.Arrays;
27import java.util.regex.Matcher;
28import java.util.regex.Pattern;
29
30/**
31 * Tests command alias functionality
32 *
33 * @author rodionmoiseev
34 */
35public class CommandAliasTest {
36  @Test
37  public void oneCommandWithSingleAlias() {
38    CommandMain cm = new CommandMain();
39    JCommander jc = new JCommander(cm);
40    CommandAdd add = new CommandAdd();
41    jc.addCommand("add", add, "a");
42    jc.parse("a", "-i", "A.java");
43
44    Assert.assertEquals(jc.getParsedCommand(), "add");
45    Assert.assertEquals(jc.getParsedAlias(), "a");
46    Assert.assertEquals(add.interactive.booleanValue(), true);
47    Assert.assertEquals(add.patterns, Arrays.asList("A.java"));
48  }
49
50  @Test
51  public void oneCommandWithMultipleAliases_commit_ci() {
52    testCommitWithAlias("ci");
53  }
54
55  @Test
56  public void oneCommandWithMultipleAliases_commit_cmt() {
57    testCommitWithAlias("cmt");
58  }
59
60  private void testCommitWithAlias(String alias) {
61    CommandMain cm = new CommandMain();
62    JCommander jc = new JCommander(cm);
63    CommandCommit commit = new CommandCommit();
64    jc.addCommand("commit", commit, "ci", "cmt");
65    jc.parse(alias, "--amend", "--author", "jack", "file1.txt");
66
67    Assert.assertEquals(jc.getParsedCommand(), "commit");
68    Assert.assertEquals(jc.getParsedAlias(), alias);
69    Assert.assertEquals(commit.amend.booleanValue(), true);
70    Assert.assertEquals(commit.author, "jack");
71    Assert.assertEquals(commit.files, Arrays.asList("file1.txt"));
72  }
73
74  @Test
75  public void twoCommandsWithAliases() {
76    CommandMain cm = new CommandMain();
77    JCommander jc = new JCommander(cm);
78    CommandAdd add = new CommandAdd();
79    jc.addCommand("add", add, "a");
80    CommandCommit commit = new CommandCommit();
81    jc.addCommand("commit", commit, "ci", "cmt");
82    jc.parse("a", "-i", "A.java");
83
84    Assert.assertEquals(jc.getParsedCommand(), "add");
85    Assert.assertEquals(add.interactive.booleanValue(), true);
86    Assert.assertEquals(add.patterns, Arrays.asList("A.java"));
87  }
88
89  @Test
90  public void clashingAliasesAreNotAllowed() {
91    CommandMain cm = new CommandMain();
92    JCommander jc = new JCommander(cm);
93    CommandAdd add = new CommandAdd();
94    jc.addCommand("add", add, "xx");
95    CommandCommit commit = new CommandCommit();
96    try {
97      jc.addCommand("commit", commit, "ci", "xx");
98      Assert.fail("Should not be able to register clashing alias 'xx'");
99    } catch (ParameterException pe) {
100      //Make sure the message mentions that "xx" aliases is already
101      //defined for "add" command
102      Assert.assertTrue(pe.getMessage().contains("xx"));
103      Assert.assertTrue(pe.getMessage().contains("add"));
104    }
105  }
106
107  @Test
108  public void mainCommandReturnsNullsForGetCommandAndGetParsedAlias() {
109    CommandMain cm = new CommandMain();
110    JCommander jc = new JCommander(cm);
111    Assert.assertNull(jc.getParsedCommand());
112    Assert.assertNull(jc.getParsedAlias());
113  }
114
115  @Test
116  public void usageCanBeRetrievedWithBothCommandAndAlias() {
117    CommandMain cm = new CommandMain();
118    JCommander jc = new JCommander(cm);
119    CommandCommit commit = new CommandCommit();
120    jc.addCommand("commit", commit, "ci", "cmt");
121    StringBuilder out = new StringBuilder();
122    jc.usage("commit", out);
123    patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1);
124
125    out = new StringBuilder();
126    jc.usage("ci", out);
127    patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1);
128
129    out = new StringBuilder();
130    jc.usage("cmt", out);
131    patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1);
132  }
133
134  @Test
135  public void usageDisplaysCommandWithAliasesOnlyOnce() {
136    CommandMain cm = new CommandMain();
137    JCommander jc = new JCommander(cm);
138    CommandCommit commit = new CommandCommit();
139    jc.addCommand("commit", commit, "ci", "cmt");
140    StringBuilder out = new StringBuilder();
141    jc.usage(out);
142    // The usage should display this string twice: one as the command name
143    // and one after Usage:
144    patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 2);
145  }
146
147  /**
148   * Visually test the formatting for "prettiness"
149   */
150  @Test(enabled = false, description = "TODO: test the output instead of displaying it")
151  public void formattingLooksNice(){
152    CommandMain cm = new CommandMain();
153    JCommander jc = new JCommander(cm);
154    CommandAdd add = new CommandAdd();
155    jc.addCommand("add", add, "a");
156    CommandCommit commit = new CommandCommit();
157    jc.addCommand("commit", commit, "ci", "cmt");
158    StringBuilder sb = new StringBuilder();
159    jc.usage(sb);
160    System.out.println("--- usage() formatting ---");
161    System.out.println(sb.toString());
162
163    sb = new StringBuilder();
164    jc.usage("commit", sb);
165    System.out.println("--- usage('commit') formatting ---");
166    System.out.println(sb.toString());
167  }
168
169  private void patternMatchesTimes(String pattern, String input, int times) {
170    Matcher m = Pattern.compile(pattern).matcher(input);
171    int matches = 0;
172    while (m.find()) matches++;
173    Assert.assertEquals(matches, times);
174  }
175}
176