001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.test.json;
018
019import java.io.File;
020import java.io.InputStream;
021import java.nio.charset.Charset;
022
023import org.springframework.core.io.Resource;
024import org.springframework.util.Assert;
025
026/**
027 * AssertJ based JSON tester that works with basic JSON strings. Allows testing of JSON
028 * payloads created from any source, for example:<pre class="code">
029 * public class ExampleObjectJsonTests {
030 *
031 *     private BasicJsonTester json = new BasicJsonTester(getClass());
032 *
033 *     &#064;Test
034 *     public void testWriteJson() throws IOException {
035 *         assertThat(json.from("example.json")).extractingJsonPathStringValue("@.name")
036                                .isEqualTo("Spring");
037 *     }
038 *
039 * }
040 * </pre>
041 *
042 * See {@link AbstractJsonMarshalTester} for more details.
043 *
044 * @author Phillip Webb
045 * @author Andy Wilkinson
046 * @since 1.4.0
047 */
048public class BasicJsonTester {
049
050        private JsonLoader loader;
051
052        /**
053         * Create a new uninitialized {@link BasicJsonTester} instance.
054         */
055        protected BasicJsonTester() {
056        }
057
058        /**
059         * Create a new {@link BasicJsonTester} instance that will load resources as UTF-8.
060         * @param resourceLoadClass the source class used to load resources
061         */
062        public BasicJsonTester(Class<?> resourceLoadClass) {
063                this(resourceLoadClass, null);
064        }
065
066        /**
067         * Create a new {@link BasicJsonTester} instance.
068         * @param resourceLoadClass the source class used to load resources
069         * @param charset the charset used to load resources
070         * @since 1.4.1
071         */
072        public BasicJsonTester(Class<?> resourceLoadClass, Charset charset) {
073                Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
074                this.loader = new JsonLoader(resourceLoadClass, charset);
075        }
076
077        /**
078         * Initialize the marshal tester for use, configuring it to load JSON resources as
079         * UTF-8.
080         * @param resourceLoadClass the source class used when loading relative classpath
081         * resources
082         */
083        protected final void initialize(Class<?> resourceLoadClass) {
084                this.initialize(resourceLoadClass, null);
085        }
086
087        /**
088         * Initialize the marshal tester for use.
089         * @param resourceLoadClass the source class used when loading relative classpath
090         * resources
091         * @param charset the charset used when loading relative classpath resources
092         * @since 1.4.1
093         */
094        protected final void initialize(Class<?> resourceLoadClass, Charset charset) {
095                if (this.loader == null) {
096                        this.loader = new JsonLoader(resourceLoadClass, charset);
097                }
098        }
099
100        /**
101         * Create JSON content from the specified String source. The source can contain the
102         * JSON itself or, if it ends with {@code .json}, the name of a resource to be loaded
103         * using {@code resourceLoadClass}.
104         * @param source the JSON content or a {@code .json} resource name
105         * @return the JSON content
106         */
107        public JsonContent<Object> from(CharSequence source) {
108                verify();
109                return getJsonContent(this.loader.getJson(source));
110        }
111
112        /**
113         * Create JSON content from the specified resource path.
114         * @param path the path of the resource to load
115         * @param resourceLoadClass the source class used to load the resource
116         * @return the JSON content
117         */
118        public JsonContent<Object> from(String path, Class<?> resourceLoadClass) {
119                verify();
120                return getJsonContent(this.loader.getJson(path, resourceLoadClass));
121        }
122
123        /**
124         * Create JSON content from the specified JSON bytes.
125         * @param source the bytes of JSON
126         * @return the JSON content
127         */
128        public JsonContent<Object> from(byte[] source) {
129                verify();
130                return getJsonContent(this.loader.getJson(source));
131        }
132
133        /**
134         * Create JSON content from the specified JSON file.
135         * @param source the file containing JSON
136         * @return the JSON content
137         */
138        public JsonContent<Object> from(File source) {
139                verify();
140                return getJsonContent(this.loader.getJson(source));
141        }
142
143        /**
144         * Create JSON content from the specified JSON input stream.
145         * @param source the input stream containing JSON
146         * @return the JSON content
147         */
148        public JsonContent<Object> from(InputStream source) {
149                verify();
150                return getJsonContent(this.loader.getJson(source));
151        }
152
153        /**
154         * Create JSON content from the specified JSON resource.
155         * @param source the resource containing JSON
156         * @return the JSON content
157         */
158        public JsonContent<Object> from(Resource source) {
159                verify();
160                return getJsonContent(this.loader.getJson(source));
161        }
162
163        private void verify() {
164                Assert.state(this.loader != null, "Uninitialized BasicJsonTester");
165        }
166
167        private JsonContent<Object> getJsonContent(String json) {
168                return new JsonContent<>(this.loader.getResourceLoadClass(), null, json);
169        }
170
171}