View | Details | Raw Unified | Return to bug 61759
Collapse All | Expand All

(-)src/core/org/apache/jmeter/resources/messages.properties (+2 lines)
Lines 176-181 Link Here
176
cancel_new_from_template=There are test items that have not been saved.  Do you wish to save before creating a test plan from selected template?
176
cancel_new_from_template=There are test items that have not been saved.  Do you wish to save before creating a test plan from selected template?
177
cancel_new_to_save=There are test items that have not been saved.  Do you wish to save before clearing the test plan?
177
cancel_new_to_save=There are test items that have not been saved.  Do you wish to save before clearing the test plan?
178
cancel_revert_project=There are test items that have not been saved.  Do you wish to revert to the previously saved test plan?
178
cancel_revert_project=There are test items that have not been saved.  Do you wish to revert to the previously saved test plan?
179
change_case_string=String to change case
180
change_case_mode=Change case mode UPPER(default),LOWER,CAPITALIZE,CAMEL_CASE,CAMEL_CASE_FIRST_LOWER 
179
change_parent=Change Controller
181
change_parent=Change Controller
180
char_value=Unicode character number (decimal or 0xhex)
182
char_value=Unicode character number (decimal or 0xhex)
181
check_return_code_title=Check Return Code
183
check_return_code_title=Check Return Code
(-)src/functions/org/apache/jmeter/functions/ChangeCase.java (+161 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  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
19
package org.apache.jmeter.functions;
20
21
import java.util.Arrays;
22
import java.util.Collection;
23
import java.util.EnumSet;
24
import java.util.LinkedList;
25
import java.util.List;
26
27
import org.apache.commons.lang3.StringUtils;
28
import org.apache.jmeter.engine.util.CompoundVariable;
29
import org.apache.jmeter.samplers.SampleResult;
30
import org.apache.jmeter.samplers.Sampler;
31
import org.apache.jmeter.util.JMeterUtils;
32
33
/**
34
 * Change Case Function
35
 * 
36
 * Support String manipulations of: upper case, lower case, capitalize and camel
37
 * cases
38
 * 
39
 * @since 4.0
40
 *
41
 */
42
public class ChangeCase extends AbstractFunction {
43
44
	private static final String NOT_ALPHANUMERIC_REGEX = "[^a-zA-Z]";
45
	private static final List<String> desc = new LinkedList<>();
46
	private static final String KEY = "__changeCase";
47
48
	private static final int MIN_PARAMETER_COUNT = 1;
49
	private static final int MAX_PARAMETER_COUNT = 3;
50
51
	static {
52
		desc.add(JMeterUtils.getResString("change_case_string"));
53
		desc.add(JMeterUtils.getResString("change_case_mode"));
54
		desc.add(JMeterUtils.getResString("function_name_paropt"));
55
	}
56
57
	private CompoundVariable[] values;
58
59
	@Override
60
	public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
61
		String originalString = values[0].execute();
62
		String mode = ChangeCaseMode.UPPER.getName(); // default
63
		if (values.length > 1) {
64
			mode = values[1].execute();
65
		}
66
		String targetString = changeCase(originalString, mode);
67
		addVariableValue(targetString, values, 2);
68
		return targetString;
69
	}
70
71
	protected String changeCase(String originalString, String mode) {
72
		String targetString = originalString;
73
		// mode is case insensitive, allow upper for example
74
		ChangeCaseMode changeCaseMode = ChangeCaseMode.typeOf(mode.toUpperCase());
75
		if (changeCaseMode != null) {
76
			switch (changeCaseMode) {
77
			case UPPER:
78
				targetString = StringUtils.upperCase(originalString);
79
				break;
80
			case LOWER:
81
				targetString = StringUtils.lowerCase(originalString);
82
				break;
83
			case CAPITALIZE:
84
				targetString = StringUtils.capitalize(originalString);
85
				break;
86
			case CAMEL_CASE:
87
				targetString = camel(originalString, false);
88
				break;
89
			case CAMEL_CASE_FIRST_LOWER:
90
				targetString = camel(originalString, true);
91
				break;
92
			default:
93
				// default not doing nothing to string
94
			}
95
		}
96
		return targetString;
97
	}
98
99
	@Override
100
	public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
101
		checkParameterCount(parameters, MIN_PARAMETER_COUNT, MAX_PARAMETER_COUNT);
102
		values = parameters.toArray(new CompoundVariable[parameters.size()]);
103
	}
104
105
	@Override
106
	public String getReferenceKey() {
107
		return KEY;
108
	}
109
110
	@Override
111
	public List<String> getArgumentDesc() {
112
		return desc;
113
	}
114
115
	private static String camel(String str, boolean isFirstCapitalied) {
116
		StringBuffer buff = new StringBuffer();
117
		List<String> tokens = Arrays.asList(str.split(NOT_ALPHANUMERIC_REGEX));
118
		if (isFirstCapitalied) {
119
			buff.append(tokens.get(0));
120
			tokens = tokens.subList(1, tokens.size());
121
		}
122
		for (String i : tokens) {
123
			buff.append(StringUtils.capitalize(i));
124
		}
125
		return buff.toString();
126
	}
127
128
	/**
129
	 * ChangeCase Modes
130
	 * 
131
	 * Modes for different cases
132
	 *
133
	 */
134
	public enum ChangeCaseMode {
135
		UPPER("UPPER"), LOWER("LOWER"), CAPITALIZE("CAPITALIZE"), CAMEL_CASE("CAMEL_CASE"), CAMEL_CASE_FIRST_LOWER("CAMEL_CASE_FIRST_LOWER");
136
		private String mode;
137
138
		private ChangeCaseMode(String mode) {
139
			this.mode = mode;
140
		}
141
142
		public String getName() {
143
			return this.mode;
144
		}
145
146
		/**
147
		 * Get ChangeCaseMode by mode
148
		 * 
149
		 * @param mode
150
		 * @return relevant ChangeCaseMode
151
		 */
152
		public static ChangeCaseMode typeOf(String mode) {
153
			EnumSet<ChangeCaseMode> allOf = EnumSet.allOf(ChangeCaseMode.class);
154
			for (ChangeCaseMode zs : allOf) {
155
				if (zs.getName().equals(mode))
156
					return zs;
157
			}
158
			return null;
159
		}
160
	}
161
}
(-)test/src/org/apache/jmeter/functions/TestChangeCase.java (+138 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  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
19
package org.apache.jmeter.functions;
20
21
import static org.junit.Assert.assertEquals;
22
23
import java.util.Collection;
24
import java.util.LinkedList;
25
26
import org.apache.jmeter.engine.util.CompoundVariable;
27
import org.apache.jmeter.junit.JMeterTestCase;
28
import org.apache.jmeter.samplers.SampleResult;
29
import org.apache.jmeter.threads.JMeterContext;
30
import org.apache.jmeter.threads.JMeterContextService;
31
import org.apache.jmeter.threads.JMeterVariables;
32
import org.junit.Before;
33
import org.junit.Test;
34
35
/**
36
 * Test{@link ChangeCase} ChangeCase
37
 *  
38
 * @see ChangeCase 
39
 *
40
 */
41
public class TestChangeCase extends JMeterTestCase {
42
	
43
	protected AbstractFunction changeCase;
44
	private SampleResult result;
45
46
    private Collection<CompoundVariable> params;
47
48
    private JMeterVariables vars;
49
50
    private JMeterContext jmctx;
51
52
    @Before
53
    public void setUp() {
54
    	changeCase = new ChangeCase();
55
        result = new SampleResult();
56
        jmctx = JMeterContextService.getContext();
57
        String data = "dummy data";
58
        result.setResponseData(data, null);
59
        vars = new JMeterVariables();
60
        jmctx.setVariables(vars);
61
        jmctx.setPreviousResult(result);
62
        params = new LinkedList<>();
63
    }
64
65
    @Test
66
    public void testParameterCountIsPropDefined() throws Exception {
67
        checkInvalidParameterCounts(changeCase, 1, 3);
68
    }
69
    
70
    @Test
71
    public void testChangeCase() throws Exception {
72
    	params.add(new CompoundVariable("myUpperTest"));
73
    	changeCase.setParameters(params);
74
    	String returnValue = changeCase.execute(result, null);
75
    	assertEquals("MYUPPERTEST", returnValue);
76
    }
77
78
    @Test
79
    public void testChangeCaseLower() throws Exception {
80
    	params.add(new CompoundVariable("myUpperTest"));
81
    	params.add(new CompoundVariable("LOWER"));
82
    	changeCase.setParameters(params);
83
    	String returnValue = changeCase.execute(result, null);
84
    	assertEquals("myuppertest", returnValue);
85
    }
86
    
87
    @Test
88
    public void testChangeCaseWrongMode() throws Exception {
89
    	params.add(new CompoundVariable("myUpperTest"));
90
    	params.add(new CompoundVariable("Wrong"));
91
    	changeCase.setParameters(params);
92
    	String returnValue = changeCase.execute(result, null);
93
    	assertEquals("myUpperTest", returnValue);
94
    }
95
    
96
    @Test
97
    public void testChangeCaseCamelCase() throws Exception {
98
    	params.add(new CompoundVariable("ab-CD eF"));
99
    	params.add(new CompoundVariable("CAMEL_CASE"));
100
    	changeCase.setParameters(params);
101
    	String returnValue = changeCase.execute(result, null);
102
    	assertEquals("AbCDEF", returnValue);
103
    }
104
    
105
    @Test
106
    public void testChangeCaseCapitalize() throws Exception {
107
    	params.add(new CompoundVariable("ab-CD eF"));
108
    	params.add(new CompoundVariable("CAPITALIZE"));
109
    	changeCase.setParameters(params);
110
    	String returnValue = changeCase.execute(result, null);
111
    	assertEquals("Ab-CD eF", returnValue);
112
    }
113
    
114
    @Test
115
    public void testChangeCaseCamelCaseFirstLower() throws Exception {
116
    	params.add(new CompoundVariable("ab-CD eF"));
117
        params.add(new CompoundVariable("camel_CASE_FIRST_LOWER"));
118
        changeCase.setParameters(params);
119
        String returnValue = changeCase.execute(result, null);
120
        assertEquals("abCDEF", returnValue);
121
    }
122
    
123
    @Test(expected=InvalidVariableException.class)
124
	public void testChangeCaseError() throws Exception {
125
		changeCase.setParameters(params);
126
		changeCase.execute(result, null);
127
	}    
128
129
    @Test
130
    public void testChangeCaseWrongModeIgonre() throws Exception {
131
    	params.add(new CompoundVariable("ab-CD eF"));
132
        params.add(new CompoundVariable("Wrong"));
133
        changeCase.setParameters(params);
134
        String returnValue = changeCase.execute(result, null);
135
        assertEquals("ab-CD eF", returnValue);
136
    }
137
138
}
(-)xdocs/changes.xml (+1 lines)
Lines 136-141 Link Here
136
    <li><bug>61724</bug>Add <code>__digest</code> function to provide computing of Hashes (SHA-XXX, MDX). Based on a contribution by orimarko at gmail.com</li>
136
    <li><bug>61724</bug>Add <code>__digest</code> function to provide computing of Hashes (SHA-XXX, MDX). Based on a contribution by orimarko at gmail.com</li>
137
    <li><bug>61735</bug>Add <code>__dateTimeConvert</code> function to provide date formats conversions. Based on a contribution by orimarko at gmail.com</li>
137
    <li><bug>61735</bug>Add <code>__dateTimeConvert</code> function to provide date formats conversions. Based on a contribution by orimarko at gmail.com</li>
138
    <li><bug>61760</bug>Add <code>__isPropDefined</code> and <code>__isVarDefined</code> functions to know if property or variable exist. Contributed by orimarko at gmail.com</li>
138
    <li><bug>61760</bug>Add <code>__isPropDefined</code> and <code>__isVarDefined</code> functions to know if property or variable exist. Contributed by orimarko at gmail.com</li>
139
    <li><bug>61759</bug>Add <code>__changeCase</code> function to change different cases of a string. Contributed by orimarko at gmail.com</li>
139
</ul>
140
</ul>
140
141
141
<h3>I18N</h3>
142
<h3>I18N</h3>
(-)xdocs/usermanual/functions.xml (-2 / +26 lines)
Lines 1616-1622 Link Here
1616
        <property name="Name of variable" required="No">The name of the variable to set.</property>
1616
        <property name="Name of variable" required="No">The name of the variable to set.</property>
1617
    </properties>
1617
    </properties>
1618
</component>
1618
</component>
1619
<component index="&sect-num;.5.35" name="__isPropDefined">
1619
<component index="&sect-num;.5.36" name="__isPropDefined">
1620
    <description>
1620
    <description>
1621
        <p>The __isPropDefined function returns true if property exists or false if not.</p>
1621
        <p>The __isPropDefined function returns true if property exists or false if not.</p>
1622
    </description>
1622
    </description>
Lines 1626-1632 Link Here
1626
        </property>        
1626
        </property>        
1627
    </properties>
1627
    </properties>
1628
</component>
1628
</component>
1629
<component index="&sect-num;.5.35" name="__isVarDefined">
1629
<component index="&sect-num;.5.37" name="__isVarDefined">
1630
    <description>
1630
    <description>
1631
        <p>The isVarDefined function returns true if variable exists or false if not.</p>
1631
        <p>The isVarDefined function returns true if variable exists or false if not.</p>
1632
    </description>
1632
    </description>
Lines 1636-1641 Link Here
1636
        </property>        
1636
        </property>        
1637
    </properties>
1637
    </properties>
1638
</component>
1638
</component>
1639
<component index="&sect-num;.5.38" name="__changeCase">
1640
    <description>
1641
        <p>The change case function returns a string value changing
1642
            specific case mode with the optional variable name.</p>
1643
    </description>
1644
    <properties>
1645
    <property name="String to change its case" required="Yes"> The String
1646
            that its case will be changed</property>
1647
        <property name="change case mode" required="Yes">
1648
            The mode to be used to change case, for exaple for ab-CD eF:
1649
            <ul>
1650
                <li><code>UPPER</code> result as AB-CD EF</li>
1651
                <li><code>LOWER</code> result as ab-cd ed</li>
1652
                <li><code>CAPITALIZE</code> result as Ab-CD eF</li>
1653
                <li><code>CAMEL_CASE</code>result as AbCDEF</li>
1654
                <li><code>CAMEL_CASE_FIRST_LOWER</code>result as abCDEF</li>
1655
            </ul>
1656
            <note>mode is case insensitive</note>
1657
        </property>
1658
        <property name="Name of variable" required="No">The name of
1659
            the variable to set.</property>
1660
    </properties>
1661
</component>
1662
1639
</subsection>
1663
</subsection>
1640
1664
1641
<subsection name="&sect-num;.6 Pre-defined Variables" anchor="predefinedvars">
1665
<subsection name="&sect-num;.6 Pre-defined Variables" anchor="predefinedvars">

Return to bug 61759