How to use Classes class of org.assertj.core.internal package

Best Assertj code snippet using org.assertj.core.internal.Classes

Source:ClassDiagramSolution.java Github

copy

Full Screen

...25 26 protected Map<String,String> inheritance;27 protected Map<String,Set<String>> associations;28 //include classes in the JDK etc? Can produce crowded diagrams.29 protected boolean includeLibraryClasses = true;30 protected Set<String> allClassNames;31 32 protected Set<String> desiredClasses = new HashSet<String>();33// hard-coded class name list34// Arrays.asList(35// "org.assertj.core.api.AbstractIterableAssert",36// "org.assertj.core.internal.Arrays",37// "org.assertj.core.internal.Iterables",38// "org.assertj.core.api.AbstractObjectArrayAssert",39// "org.assertj.core.api.AtomicReferenceArrayAssert",40// "org.assertj.core.internal.Strings",41// "org.assertj.core.internal.Objects",42// "org.assertj.core.internal.DeepDifference",43// "org.assertj.core.presentation.StandardRepresentation",44// "org.assertj.core.api.AbstractDateAssert",45// "org.assertj.core.internal.Maps",46// "org.assertj.core.internal.Dates",47// "org.assertj.core.internal.Classes",48// "org.assertj.core.api.AbstractAssert",49// "org.assertj.core.api.AbstractMapAssert",50// "org.assertj.core.api.Assertions",51// "org.assertj.core.api.WithAssertions",52// "org.assertj.core.util.diff.DiffUtils",53// "org.assertj.core.internal.Paths",54// "org.assertj.core.api.Java6Assertions",55// "org.assertj.core.api.Assumptions",56// "org.assertj.core.internal.ObjectArrays",57// "org.assertj.core.api.AbstractCharSequenceAssert",58// "org.assertj.core.api.ListAssert",59// "org.assertj.core.api.AbstractFloatAssert",60// "org.assertj.core.api.AbstractDoubleAssert",61// "org.assertj.core.api.IterableAssert",62// "org.assertj.core.api.AbstractZonedDateTimeAssert",63// "org.assertj.core.api.AssertionsForClassTypes",64// "org.assertj.core.api.AbstractOffsetDateTimeAssert",65// "org.assertj.core.api.AbstractListAssert",66// "org.assertj.core.util.Files",67// "org.assertj.core.api.AbstractOffsetTimeAssert",68// "org.assertj.core.api.AbstractByteArrayAssert"));69 List<ClassInfo> desiredClassInfoList = new ArrayList<ClassInfo>();70 71 public static List<Class<?>> processDirectory(File directory, String pkgname) {72 ArrayList<Class<?>> classes = new ArrayList<Class<?>>();73 String prefix = pkgname+".";74 if(pkgname.equals(""))75 prefix = "";76 // Get the list of the files contained in the package77 String[] files = directory.list();78 for (int i = 0; i < files.length; i++) {79 String fileName = files[i];80 String className = null;81 // we are only interested in .class files82 if (fileName.endsWith(".class")) {83 // removes the .class extension84 className = prefix+fileName.substring(0, fileName.length() - 6);85 }86 if (className != null) {87 Class loaded = loadClass(className);88 if(loaded!=null)89 classes.add(loaded);90 }91 //If the file is a directory recursively class this method.92 File subdir = new File(directory, fileName);93 if (subdir.isDirectory()) {94 classes.addAll(processDirectory(subdir, prefix + fileName));95 }96 }97 return classes;98 }99 private static Class<?> loadClass(String className) {100 try {101 return Class.forName(className);102 //return Class.forName(className, true, classLoader);103 }104 catch (ClassNotFoundException e) {105 //throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'");106 return null;107 }108 catch (Error e){109 return null;110 }111 }112 /**113 * Instantiating the class will populate the inheritance and association relations.114 * @param root115 * @throws MalformedURLException 116 */117 public ClassDiagramSolution(String root, boolean includeLibs) throws MalformedURLException{118 119 try {120 desiredClassInfoList = ClassMetrics.getClasses(300);121 122 for (ClassInfo cinfo : desiredClassInfoList) {123 String className = cinfo.getName().replaceAll("/", ".");124 desiredClasses.add(className);125 }126 } catch (IOException e) {127 // error occurred during class diagram128 e.printStackTrace();129 }130 131 File file = new File(mainJarPath);132 classLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()});133 134 this.includeLibraryClasses = includeLibs;135 File dir = new File(root);136 List<Class<?>> classes = processDirectory(dir,"");137 inheritance = new HashMap<String, String>();138 associations = new HashMap<String, Set<String>>();139 allClassNames = new HashSet<String>();140 for(Class cl : classes){141 if (desiredClasses.contains(cl.getName())) {142 allClassNames.add(cl.getName());143 }144 }145 for(Class cl : classes){146 if(cl.isInterface())147 continue;148 if (desiredClasses.contains(cl.getName())) {149 inheritance.put(cl.getName(),cl.getSuperclass().getName());150 Set<String> fields = new HashSet<String>();151 for(Field fld : cl.getDeclaredFields()){152 //Do not want to include associations to primitive types such as ints or doubles.153 if(!fld.getType().isPrimitive()) {154 fields.add(fld.getType().getName());155 }156 }157 associations.put(cl.getName(),fields);158 }159 }160 }161 162 /**163 * Write out the class diagram to a specified file.164 * @param target165 */166 public void writeDot(File target) throws IOException {167 BufferedWriter fw = new BufferedWriter(new FileWriter(target));168 StringBuffer dotGraph = new StringBuffer();169 Collection<String> dotGraphClasses = new HashSet<String>(); //need this to specify that shape of each class should be a square.170 dotGraph.append("digraph classDiagram{\n"171 + "graph [splines=ortho]\n\n");172 //Add inheritance relations173 for(String childClass : inheritance.keySet()){174 String from = "\""+childClass +"\"";175 dotGraphClasses.add(from);176 String to = "\""+inheritance.get(childClass)+"\"";177 if(!includeLibraryClasses){178 if(!allClassNames.contains(inheritance.get(childClass)))179 continue;180 }181 dotGraphClasses.add(to);182 dotGraph.append(from+ " -> "+to+"[arrowhead = onormal];\n");183 }184 //Add associations185 for(String cls : associations.keySet()){186 Set<String> fields = associations.get(cls);187 for(String field : fields) {188 String from = "\""+cls +"\"";189 dotGraphClasses.add(from);190 String to = "\""+field+"\"";191 if(!includeLibraryClasses){192 if(!allClassNames.contains(field))193 continue;194 }195 dotGraphClasses.add(to);196 dotGraph.append(from + " -> " +to + "[arrowhead = diamond];\n");197 }198 }199 int maxLOC = (int) desiredClassInfoList.get(0).getMetric(Metric.LOC);200 int maxMethod = (int) desiredClassInfoList.get(0).getMetric(Metric.MethodCount);201 int maxheight = 5;202 int maxWidth = 5;203 204 if (desiredClassInfoList == null || desiredClassInfoList.size() <= 0) {205 for(String node : dotGraphClasses){206 dotGraph.append(node+ "[shape = box];\n");207 }208 } else {209 for(ClassInfo node : desiredClassInfoList){210 // Depth of inheritance - FontSize, 211 // LOC - Height of Box and 212 // Number of methods - Width of the box213 // are used for visualizing the class in an intuitive way 214 double w = (double) (maxWidth * node.getMetric(Metric.MethodCount)) / (double) maxMethod;215 double h = (double) (maxheight * node.getMetric(Metric.LOC)) / (double) maxLOC;216 double fontsize = (node.getMetric(Metric.DepthOfInheritance) + 1) * 8.0;217 String className = "\"" + node.getName().replaceAll("/", ".") + "\"";218 dotGraph.append(className + "[shape = box"219 + ", fontsize=" + fontsize ...

Full Screen

Full Screen

Source:Classes_assertIsNotAnnotation_Test.java Github

copy

Full Screen

...16import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;17import static org.assertj.core.util.FailureMessages.actualIsNull;18import static org.mockito.Mockito.verify;19import org.assertj.core.api.AssertionInfo;20import org.assertj.core.internal.ClassesBaseTest;21import org.junit.Test;22/**23 * Tests for24 * <code>{@link org.assertj.core.internal.Classes#assertIsNotAnnotation(org.assertj.core.api.AssertionInfo, Class)}</code>25 * .26 * 27 * @author William Delanoue28 */29public class Classes_assertIsNotAnnotation_Test extends ClassesBaseTest {30 @Test31 public void should_fail_if_actual_is_null() {32 actual = null;33 thrown.expectAssertionError(actualIsNull());34 classes.assertIsNotAnnotation(someInfo(), actual);35 }36 @Test37 public void should_pass_if_actual_is_not_an_annotation() {38 actual = Classes_assertIsNotAnnotation_Test.class;39 classes.assertIsNotAnnotation(someInfo(), actual);40 }41 @Test()42 public void should_fail_if_actual_is_an_annotation() {43 actual = Override.class;44 AssertionInfo info = someInfo();45 try {46 classes.assertIsNotAnnotation(someInfo(), actual);47 } catch (AssertionError e) {48 verify(failures).failure(info, shouldNotBeAnnotation(actual));49 return;50 }51 failBecauseExpectedAssertionErrorWasNotThrown();52 }...

Full Screen

Full Screen

Source:Classes_assertIsAnnotation_Test.java Github

copy

Full Screen

...16import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;17import static org.assertj.core.util.FailureMessages.actualIsNull;18import static org.mockito.Mockito.verify;19import org.assertj.core.api.AssertionInfo;20import org.assertj.core.internal.ClassesBaseTest;21import org.junit.Test;22/**23 * Tests for24 * <code>{@link org.assertj.core.internal.Classes#assertIsAnnotation(org.assertj.core.api.AssertionInfo, Class)}</code>25 * .26 * 27 * @author William Delanoue28 */29public class Classes_assertIsAnnotation_Test extends ClassesBaseTest {30 @Test31 public void should_fail_if_actual_is_null() {32 actual = null;33 thrown.expectAssertionError(actualIsNull());34 classes.assertIsAnnotation(someInfo(), actual);35 }36 @Test37 public void should_pass_if_actual_is_an_annotation() {38 actual = Override.class;39 classes.assertIsAnnotation(someInfo(), actual);40 }41 @Test()42 public void should_fail_if_actual_is_not_an_annotation() {43 AssertionInfo info = someInfo();44 actual = Classes_assertIsAnnotation_Test.class;45 try {46 classes.assertIsAnnotation(someInfo(), actual);47 } catch (AssertionError e) {48 verify(failures).failure(info, shouldBeAnnotation(actual));49 return;50 }51 failBecauseExpectedAssertionErrorWasNotThrown();52 }53}...

Full Screen

Full Screen

Source:Classes_assertIsNotInterface_Test.java Github

copy

Full Screen

...14import static org.assertj.core.error.ShouldBeInterface.shouldNotBeInterface;15import static org.assertj.core.test.TestData.someInfo;16import static org.assertj.core.util.FailureMessages.actualIsNull;17import org.assertj.core.api.AssertionInfo;18import org.assertj.core.internal.ClassesBaseTest;19import org.junit.Test;20/**21 * Tests for22 * <code>{@link org.assertj.core.internal.Classes#assertIsNotInterface(org.assertj.core.api.AssertionInfo, Class)}</code>23 * 24 * @author William Delanoue25 */26public class Classes_assertIsNotInterface_Test extends ClassesBaseTest {27 @Test28 public void should_fail_if_actual_is_null() {29 actual = null;30 thrown.expectAssertionError(actualIsNull());31 classes.assertIsNotInterface(someInfo(), actual);32 }33 @Test34 public void should_pass_if_actual_is_not_an_interface() {35 actual = Classes_assertIsNotInterface_Test.class;36 classes.assertIsNotInterface(someInfo(), actual);37 }38 @Test()39 public void should_fail_if_actual_is_an_interface() {40 actual = AssertionInfo.class;41 thrown.expectAssertionError(shouldNotBeInterface(actual));42 classes.assertIsNotInterface(someInfo(), actual);43 }44}...

Full Screen

Full Screen

Source:Classes_assertIsInterface_Test.java Github

copy

Full Screen

...14import static org.assertj.core.error.ShouldBeInterface.shouldBeInterface;15import static org.assertj.core.test.TestData.someInfo;16import static org.assertj.core.util.FailureMessages.actualIsNull;17import org.assertj.core.api.AssertionInfo;18import org.assertj.core.internal.ClassesBaseTest;19import org.junit.Test;20/**21 * Tests for22 * <code>{@link org.assertj.core.internal.Classes#assertIsInterface(org.assertj.core.api.AssertionInfo, Class)}</code> .23 * 24 * @author William Delanoue25 */26public class Classes_assertIsInterface_Test extends ClassesBaseTest {27 @Test28 public void should_fail_if_actual_is_null() {29 actual = null;30 thrown.expectAssertionError(actualIsNull());31 classes.assertIsInterface(someInfo(), actual);32 }33 @Test34 public void should_pass_if_actual_is_an_interface() {35 actual = AssertionInfo.class;36 classes.assertIsInterface(someInfo(), actual);37 }38 @Test()39 public void should_fail_if_actual_is_not_an_interface() {40 actual = Classes_assertIsInterface_Test.class;41 thrown.expectAssertionError(shouldBeInterface(actual));42 classes.assertIsInterface(someInfo(), actual);43 }44}...

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1import static org.assertj.core.api.Assertions.assertThat;2import static org.assertj.core.api.Assertions.assertThatThrownBy;3import static org.assertj.core.api.Assertions.catchThrowable;4import static org.assertj.core.api.Assertions.catchThrowableOfType;5import static org.assertj.core.api.Assertions.contentOf;6import static org.assertj.core.api.Assertions.contentOfURL;7import static org.assertj.core.a

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1import static org.assertj.core.api.Assertions.assertThat;2import static org.assertj.core.api.Assertions.assertThatExceptionOfType;3import static org.assertj.core.api.Assertions.catchThrowable;4import static org.assertj.core.api.Assertions.catchThrowableOfType;5import static org.assertj.core.api.Assertions.fail;6import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;7import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;8import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;9import static org.assertj.core.api.Assertions.assertThat;10import static org.assertj.core.api.Assertions.assertThatExceptionOfType;11import static org.assertj.core.api.Assertions.catchThrowable;12import static org.assertj.core.api.Assertions.catchThrowableOfType;13import static org.assertj.core.api.Assertions.fail;14import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;15import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;16import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;17import static org.assertj.core.api.Assertions.assertThat;18import static org.assertj.core.api.Assertions.assertThatExceptionOfType;19import static org.assertj.core.api.Assertions.catchThrowable;20import static org.assertj.core.api.Assertions.catchThrowableOfType;21import static org.assertj.core.api.Assertions.fail;22import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;23import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;24import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;25import static org.assertj.core.api.Assertions.assertThat;26import static org.assertj.core.api.Assertions.assertThatExceptionOfType;27import static org.assertj.core.api.Assertions.catchThrowable;28import static org.assertj.core.api.Assertions.catchThrowableOfType;29import static org.assertj.core.api.Assertions.fail;30import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;31import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;32import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;33import static org.assertj.core.api.Assertions.assertThat;34import static org.assertj.core.api.Assertions.assertThatExceptionOfType;35import static org.assertj.core.api.Assertions.catchThrowable;36import static org.assertj.core.api.Assertions.catchThrowableOfType;37import static org.assertj.core.api.Assertions.fail;38import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;39import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1package org.assertj.core.internal;2import org.assertj.core.api.AssertionInfo;3import org.assertj.core.api.Assertions;4import org.assertj.core.util.VisibleForTesting;5import org.assertj.core.util.introspection.IntrospectionError;6import org.assertj.core.util.introspection.PropertyOrFieldSupport;7import org.assertj.core.util.introspection.PropertyReader;8public class Classes {9private static final Classes INSTANCE = new Classes();10private final PropertyOrFieldSupport propertyOrFieldSupport = new PropertyOrFieldSupport();11private final PropertyReader propertyReader = new PropertyReader();12Classes(PropertyOrFieldSupport propertyOrFieldSupport, PropertyReader propertyReader) {13 this.propertyOrFieldSupport = propertyOrFieldSupport;14 this.propertyReader = propertyReader;15}16public static Classes instance() {17 return INSTANCE;18}19public boolean hasFieldOrProperty(AssertionInfo info, Object actual, String propertyName) {20 assertNotNull(info, actual);21 return propertyOrFieldSupport.hasFieldOrProperty(actual, propertyName);22}23public Object readProperty(AssertionInfo info, Object actual, String propertyName) {24 assertNotNull(info, actual);25 try {26 return propertyReader.read(actual, propertyName);27 } catch (IntrospectionError e) {28 throw failures.failure(info, shouldHaveProperty(actual, propertyName, e));29 }30}31private void assertNotNull(AssertionInfo info, Object actual) {32 Objects.instance().assertNotNull(info, actual);33}34private Failures failures = Failures.instance();35}36package org.assertj.core.internal;37import org.assertj.core.api.AssertionInfo;38import org.assertj.core.util.VisibleForTesting;39public class Objects {40private static final Objects INSTANCE = new Objects();41Failures failures = Failures.instance();42public static Objects instance() {43 return INSTANCE;44}45public void assertNotNull(AssertionInfo info, Object actual) {46 if (actual == null) throw failures.failure(info, shouldBeNotNull());47}48private Failures failures = Failures.instance();49}50package org.assertj.core.util.introspection;51import org.assertj.core.util.introspection.IntrospectionError;52public class PropertyOrFieldSupport {53private PropertyOrFieldSupport() {}54public boolean hasFieldOrProperty(Object target, String name)

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1import org.assertj.core.internal.Classes;2import org.junit.Test;3import static org.assertj.core.api.Assertions.assertThat;4public class ClassesTest {5 public void test() {6 assertThat(Classes.class).isNotNull();7 }8}

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1package org.assertj.core.internal;2import org.junit.Test;3import static org.assertj.core.api.Assertions.assertThat;4public class ClassesTest {5 public void test() {6 Classes classes = new Classes();7 assertThat(classes).isNotNull();8 }9}

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1package org.assertj.core.api;2import org.assertj.core.internal.Classes;3import org.assertj.core.internal.ClassesBaseTest;4import org.junit.jupiter.api.BeforeEach;5import org.junit.jupiter.api.Test;6import static org.assertj.core.api.Assertions.assertThat;7import static org.assertj.core.api.Assertions.assertThatExceptionOfType;8import static org.assertj.core.test.TestData.someInfo;9import static org.assertj.core.util.AssertionsUtil.expectAssertionError;10import static org.assertj.core.util.FailureMessages.actualIsNull;11class Classes_assertHasPublicFields_Test extends ClassesBaseTest {12 void setUp() {13 actual = Classes_assertHasPublicFields_Test.class;14 }15 void should_pass_if_actual_has_public_fields() {16 classes.assertHasPublicFields(someInfo(), actual, "publicField");17 }18 void should_fail_if_actual_has_no_public_fields() {19 AssertionError assertionError = expectAssertionError(() -> classes.assertHasPublicFields(someInfo(), actual, "privateField"));20 assertThat(assertionError).hasMessageContaining("Expecting actual's fields to contain:[privateField] but could not find:[privateField]");21 }22 void should_fail_if_actual_has_no_public_fields_even_if_expected_is_empty() {23 AssertionError assertionError = expectAssertionError(() -> classes.assertHasPublicFields(someInfo(), actual));24 assertThat(assertionError).hasMessageContaining("Expecting actual's fields to contain:[] but could not find:[]");25 }26 void should_fail_if_actual_is_null() {27 actual = null;28 AssertionError error = expectAssertionError(() -> classes.assertHasPublicFields(someInfo(), actual, "publicField"));29 assertThat(error).hasMessage(actualIsNull());30 }31 void should_throw_error_if_expected_is_null() {32 assertThatExceptionOfType(NullPointerException.class).isThrownBy(() -> classes.assertHasPublicFields(someInfo(), actual, null))33 .withMessage("The names of the fields to look for should not be null");34 }35 void should_throw_error_if_expected_is_empty() {36 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> classes.assertHasPublicFields(someInfo(), actual, new String[0]))37 .withMessage("The names of the fields to

Full Screen

Full Screen

Classes

Using AI Code Generation

copy

Full Screen

1import static org.assertj.core.api.Assertions.*;2import org.assertj.core.internal.Classes;3import org.assertj.core.internal.ClassesBaseTest;4public class Classes_assertIsEqualTo_Test extends ClassesBaseTest {5 protected void initActualClass() {6 classes = new Classes();7 }8 protected Class<?> getClassUnderTest() {9 return Classes.class;10 }11 protected void verify_internal_effects() {12 assertThat(getObjects(assertions).getComparisonStrategy()).isSameAs(getObjects(otherAssertions).getComparisonStrategy());13 }14 protected Classes getObjects(Assertions assertion) {15 return ((ClassesBaseTest) assertion).classes;16 }17 protected Classes getObjects(ClassesBaseTest assertion) {18 return assertion.classes;19 }20 protected Classes getObjects(Object assertion) {21 return ((ClassesBaseTest) assertion).classes;22 }23 protected Classes getObjects(Object assertion, Object otherAssertion) {24 return ((ClassesBaseTest) assertion).classes;25 }26 protected Classes getObjects(Object assertion, Object otherAssertion, Object otherOtherAssertion) {27 return ((ClassesBaseTest) assertion).classes;28 }29 protected Classes getObjects(Object assertion, Object otherAssertion, Object otherOtherAssertion, Object otherOtherOtherAssertion) {30 return ((ClassesBaseTest) assertion).classes;31 }32}33import static org.assertj.core.api.Assertions.*;34import org.assertj.core.internal.Classes;35import org.assertj.core.internal.ClassesBaseTest;36public class Classes_assertIsNotEqualTo_Test extends ClassesBaseTest {37 protected void initActualClass() {38 classes = new Classes();39 }40 protected Class<?> getClassUnderTest() {41 return Classes.class;42 }43 protected void verify_internal_effects() {44 assertThat(getObjects(assertions).getComparisonStrategy()).isSameAs(getObjects(otherAssertions).getComparisonStrategy());45 }46 protected Classes getObjects(Assertions assertion) {47 return ((ClassesBaseTest) assertion).classes;48 }49 protected Classes getObjects(ClassesBaseTest assertion) {50 return assertion.classes;

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful