001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bct;
018
019import static org.apache.juneau.commons.utils.Shorts.*;
020
021import java.util.*;
022import java.util.function.*;
023
024import org.opentest4j.*;
025
026/**
027 * Bean-Centric Testing utility methods.
028 *
029 * <p>
030 * This class contains static utility methods specific to the Bean-Centric Testing framework.
031 * For general-purpose utility methods, use the classes in {@code org.apache.juneau.commons.utils} package.
032 *
033 * <h5 class='section'>See Also:</h5>
034 * <ul>
035 *   <li class='jc'>{@link org.apache.juneau.commons.utils.Shorts} - Terse aliases for the domain utility methods, including argument validation
036 *   <li class='jc'>{@link org.apache.juneau.commons.utils.StringUtils} - String manipulation methods
037 * </ul>
038 */
039public class BctUtils {
040
041   // BCT-specific methods
042
043   /**
044    * Creates an {@link AssertionFailedError} for failed equality assertions.
045    *
046    * <p>This method constructs a properly formatted assertion failure with expected and actual values
047    * for use in test frameworks. The message follows JUnit's standard format for assertion failures.
048    *
049    * <h5 class='section'>Example:</h5>
050    * <p class='bjava'>
051    *   <jk>if</jk> (!<jsm>eq</jsm>(<jv>expected</jv>, <jv>actual</jv>)) {
052    *       <jk>throw</jk> <jsm>assertEqualsFailed</jsm>(<jv>expected</jv>, <jv>actual</jv>, () -&gt; <js>"Custom context message with arg %s"</js>, <jv>arg</jv>);
053    *   }
054    * </p>
055    *
056    * @param expected The expected value.
057    * @param actual The actual value that was encountered.
058    * @param messageSupplier Optional supplier for additional context message.
059    * @return A new {@link AssertionFailedError} with formatted message and values.
060    */
061   public static AssertionFailedError assertEqualsFailed(Object expected, Object actual, Supplier<String> messageSupplier) {
062      return new AssertionFailedError(o(messageSupplier).map(x -> x.get()).orElse("Equals assertion failed.") + f(" ==> expected: <%s> but was: <%s>", expected, actual), expected, actual);
063   }
064
065   /**
066    * Tokenizes a string into a list of {@link NestedTokenizer.Token} objects.
067    *
068    * <p>This method delegates to {@link NestedTokenizer#tokenize(String)} to parse
069    * structured field strings into tokens. It's commonly used for parsing field lists
070    * and nested property expressions.
071    *
072    * <h5 class='section'>Example:</h5>
073    * <p class='bjava'>
074    *   <jk>var</jk> <jv>tokens</jv> = <jsm>tokenize</jsm>(<js>"name,address{street,city},age"</js>);
075    *   <jc>// Parses nested field expressions</jc>
076    * </p>
077    *
078    * @param fields The field string to tokenize.
079    * @return A list of parsed tokens.
080    * @see NestedTokenizer#tokenize(String)
081    */
082   public static List<NestedTokenizer.Token> tokenize(String fields) {
083      return NestedTokenizer.tokenize(fields);
084   }
085
086   private BctUtils() {}
087}