Advertisement
Guest User

test

a guest
Nov 15th, 2018
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 71.32 KB | None | 0 0
  1. package edu.illinois.cs.cs125.mp5.lib;
  2.  
  3. import org.testng.annotations.Test;
  4. import org.testng.Assert;
  5.  
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. import java.util.Objects;
  9.  
  10. /**
  11. * Test suite for the organic molecule analysis tests.
  12. * <p>
  13. * The provided test suite is correct and complete. You should not need to modify it.
  14. * However, you should understand it.
  15. *
  16. * @see <a href="https://cs125.cs.illinois.edu/MP/5/">MP5 Documentation</a>
  17. */
  18. public class MoleculeAnalyzerTest {
  19.  
  20. /** Timeout for analysis tests. Reference solution takes 15-31 ms from cold start. */
  21. private static final int ANALYZE_TEST_TIMEOUT = 300;
  22.  
  23. /** Timeout for molecule naming tests. Reference solution takes 1-16 ms from warm start. */
  24. private static final int NAME_TEST_TIMEOUT = 400;
  25.  
  26. /** Timeout for helper function tests. */
  27. private static final int HELPER_TEST_TIMEOUT = 350;
  28.  
  29. /** Test molecular weight calculation. */
  30. @Test(timeOut = ANALYZE_TEST_TIMEOUT)
  31. public void testMolecularWeight() {
  32. for (MoleculeAnalysisTestInput input : analysisTestCases) {
  33. MoleculeAnalyzer analyzer = new MoleculeAnalyzer(input.molecule.build());
  34. double resultWeight = analyzer.getMolecularWeight();
  35. if (Math.abs(resultWeight - input.molecularWeight) > 0.1) {
  36. Assert.assertEquals(resultWeight, input.molecularWeight);
  37. }
  38. }
  39. }
  40.  
  41. /** Test determining whether there are any charged atoms. */
  42. @Test(timeOut = ANALYZE_TEST_TIMEOUT)
  43. public void testHasCharged() {
  44. for (MoleculeAnalysisTestInput input : analysisTestCases) {
  45. MoleculeAnalyzer analyzer = new MoleculeAnalyzer(input.molecule.build());
  46. Assert.assertEquals(analyzer.hasChargedAtoms(), input.hasChargedAtom);
  47. }
  48. }
  49.  
  50. /** Test naming straight-chain alkanes with no substituents. */
  51. @Test(timeOut = NAME_TEST_TIMEOUT)
  52. public void testNamingSimpleStraight() {
  53. runNamingTest(MoleculeNamingTestDifficulty.LINEAR_ALKANE);
  54. }
  55.  
  56. /** Test naming cyclic alkanes with no substituents. */
  57. @Test(timeOut = NAME_TEST_TIMEOUT)
  58. public void testNamingSimpleCyclic() {
  59. runNamingTest(MoleculeNamingTestDifficulty.CYCLIC_ALKANE);
  60. }
  61.  
  62. /** Test naming cyclic alkanes with one non-suffix-affecting substituent. */
  63. @Test(timeOut = NAME_TEST_TIMEOUT)
  64. public void testNamingOneSubstituentCyclic() {
  65. runNamingTest(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING);
  66. }
  67.  
  68. /** Test naming linear alkanes with one non-suffix affecting substituent. Alkyl substituents cause branching. */
  69. @Test(timeOut = NAME_TEST_TIMEOUT)
  70. public void testNamingOneSubstituentLinear() {
  71. runNamingTest(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR);
  72. }
  73.  
  74. /** EXTRA CREDIT: Test naming molecules with multiple substituents. */
  75. @Test(timeOut = NAME_TEST_TIMEOUT)
  76. public void testNamingMultipleSubstituents() {
  77. runNamingTest(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS);
  78. }
  79.  
  80. /** EXTRA CREDIT: Test naming complicated molecules with multiple substituents and priority tiebreaks. */
  81. @Test(timeOut = NAME_TEST_TIMEOUT)
  82. public void testNamingPriority() {
  83. runNamingTest(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK);
  84. }
  85.  
  86. /**
  87. * Runs the naming test on the given group of molecules.
  88. * @param difficulty The difficulty/group of molecules to name.
  89. */
  90. private void runNamingTest(final MoleculeNamingTestDifficulty difficulty) {
  91. for (MoleculeNamingTestInput input : namingTestCases) {
  92. if (input.difficulty == difficulty) {
  93. MoleculeAnalyzer analyzer = new MoleculeAnalyzer(input.molecule.build());
  94. String result = analyzer.getIupacName();
  95. boolean validAnswer = false;
  96. for (String option : input.validNames) {
  97. if (option.equals(result)) {
  98. validAnswer = true;
  99. break;
  100. }
  101. }
  102. if (!validAnswer) {
  103. /*
  104. Only do an assertion if we know the answer is wrong.
  105. This way, the easiest-to-compute option will be shown in the error message,
  106. despite other fancier names being valid too.
  107. */
  108. Assert.assertEquals(result, input.validNames[0]);
  109. }
  110. }
  111. }
  112. }
  113.  
  114. private static class MoleculeAnalysisTestInput {
  115. OrganicMoleculeBuilder molecule;
  116. double molecularWeight;
  117. boolean hasChargedAtom;
  118. public MoleculeAnalysisTestInput(final OrganicMoleculeBuilder setMolecule,
  119. final double setMW, final boolean setCharge) {
  120. molecule = setMolecule;
  121. molecularWeight = setMW;
  122. hasChargedAtom = setCharge;
  123. }
  124. }
  125.  
  126. private enum MoleculeNamingTestDifficulty {
  127. LINEAR_ALKANE,
  128. CYCLIC_ALKANE,
  129. MONOSUBSTITUTED_RING,
  130. SINGLE_SUBSTITUENT_LINEAR,
  131. MULTIPLE_SUBSTITUENTS,
  132. PRIORITY_TIEBREAK
  133. }
  134.  
  135. private static class MoleculeNamingTestInput {
  136. OrganicMoleculeBuilder molecule;
  137. String[] validNames;
  138. MoleculeNamingTestDifficulty difficulty;
  139.  
  140. public MoleculeNamingTestInput(final MoleculeNamingTestDifficulty setDifficulty,
  141. final OrganicMoleculeBuilder setMolecule, final String... setNames) {
  142. molecule = setMolecule;
  143. difficulty = setDifficulty;
  144. validNames = setNames;
  145. }
  146. }
  147.  
  148. /** All the analysis (non-naming) test cases. */
  149. private static List<MoleculeAnalysisTestInput> analysisTestCases = new ArrayList<>();
  150. /** All the naming test cases. */
  151. private static List<MoleculeNamingTestInput> namingTestCases = new ArrayList<>();
  152.  
  153. static {
  154. // Analysis test cases
  155. analysisTestCases.add(new MoleculeAnalysisTestInput(
  156. new LinearOrganicMoleculeBuilder(1), 16.04, false));
  157. analysisTestCases.add(new MoleculeAnalysisTestInput(
  158. new LinearOrganicMoleculeBuilder(2), 30.07, false));
  159. analysisTestCases.add(new MoleculeAnalysisTestInput(
  160. new LinearOrganicMoleculeBuilder(3)
  161. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)),
  162. 58.12, false));
  163. analysisTestCases.add(new MoleculeAnalysisTestInput(
  164. new LinearOrganicMoleculeBuilder(3)
  165. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  166. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)),
  167. 72.15, false));
  168. analysisTestCases.add(new MoleculeAnalysisTestInput(
  169. new LinearOrganicMoleculeBuilder(2)
  170. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol(0)),
  171. 45.06, true));
  172. analysisTestCases.add(new MoleculeAnalysisTestInput(
  173. new LinearOrganicMoleculeBuilder(6), 86.18, false));
  174. analysisTestCases.add(new MoleculeAnalysisTestInput(
  175. new LinearOrganicMoleculeBuilder(5)
  176. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlcohol(2)),
  177. 89.16, true));
  178. analysisTestCases.add(new MoleculeAnalysisTestInput(
  179. new LinearOrganicMoleculeBuilder(3)
  180. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl()),
  181. 58.08, false));
  182. analysisTestCases.add(new MoleculeAnalysisTestInput(
  183. new LinearOrganicMoleculeBuilder(2)
  184. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  185. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  186. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  187. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)),
  188. 179.39, false));
  189. analysisTestCases.add(new MoleculeAnalysisTestInput(
  190. new LinearOrganicMoleculeBuilder(12)
  191. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(5))
  192. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlcohol(0))
  193. .addSubstituent(10, OrganicMoleculeBuilder.Substituent.createAlcohol(2)),
  194. 272.48, true));
  195. analysisTestCases.add(new MoleculeAnalysisTestInput(
  196. new LinearOrganicMoleculeBuilder(323),
  197. 4532.74, false));
  198.  
  199. // Naming simple straight alkanes
  200. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  201. new LinearOrganicMoleculeBuilder(1), "methane"));
  202. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  203. new LinearOrganicMoleculeBuilder(2), "ethane"));
  204. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  205. new LinearOrganicMoleculeBuilder(9), "nonane"));
  206. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  207. new LinearOrganicMoleculeBuilder(3), "propane"));
  208. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  209. new LinearOrganicMoleculeBuilder(6), "hexane"));
  210. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  211. new LinearOrganicMoleculeBuilder(4), "butane"));
  212. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  213. new LinearOrganicMoleculeBuilder(7), "heptane"));
  214. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  215. new LinearOrganicMoleculeBuilder(5), "pentane"));
  216. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  217. new LinearOrganicMoleculeBuilder(8), "octane"));
  218. /*
  219. The "substituents" on the remaining test cases in this section are at the ends of
  220. the molecule, so they actually just elongate the chain instead of add branching.
  221. This is to make sure the solution can't rely on the array indexing pattern of the builder,
  222. since what matters is the BondedAtom data structure, not the builder implementation.
  223. Several test cases in other sections use this trick as well.
  224. */
  225. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  226. new LinearOrganicMoleculeBuilder(3)
  227. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "butane"));
  228. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  229. new LinearOrganicMoleculeBuilder(4)
  230. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  231. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "heptane"));
  232. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.LINEAR_ALKANE,
  233. new LinearOrganicMoleculeBuilder(1)
  234. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(4))
  235. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(4)), "nonane"));
  236.  
  237. // Naming simple cyclic alkanes
  238. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.CYCLIC_ALKANE,
  239. new CyclicOrganicMoleculeBuilder(3), "cyclopropane"));
  240. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.CYCLIC_ALKANE,
  241. new CyclicOrganicMoleculeBuilder(10), "cyclodecane"));
  242. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.CYCLIC_ALKANE,
  243. new CyclicOrganicMoleculeBuilder(6), "cyclohexane"));
  244. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.CYCLIC_ALKANE,
  245. new CyclicOrganicMoleculeBuilder(8), "cyclooctane"));
  246. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.CYCLIC_ALKANE,
  247. new CyclicOrganicMoleculeBuilder(4), "cyclobutane"));
  248. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.CYCLIC_ALKANE,
  249. new CyclicOrganicMoleculeBuilder(5), "cyclopentane"));
  250.  
  251. // Naming cyclic alkanes with one low-priority substituent
  252. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  253. new CyclicOrganicMoleculeBuilder(3)
  254. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "1-fluorocyclopropane", "fluorocyclopropane"));
  255. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  256. new CyclicOrganicMoleculeBuilder(6)
  257. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "1-methylcyclohexane", "methylcyclohexane"));
  258. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  259. new CyclicOrganicMoleculeBuilder(8)
  260. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1-bromocyclooctane", "bromocyclooctane"));
  261. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  262. new CyclicOrganicMoleculeBuilder(4)
  263. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(3)), "1-propylcyclobutane", "propylcyclobutane"));
  264. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  265. new CyclicOrganicMoleculeBuilder(5)
  266. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlkyl(8)), "1-octylcyclopentane", "octylcyclopentane"));
  267. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  268. new CyclicOrganicMoleculeBuilder(10)
  269. .addSubstituent(9, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE)), "1-chlorocyclodecane", "chlorocyclodecane"));
  270. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  271. new CyclicOrganicMoleculeBuilder(7)
  272. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(7)), "1-heptylcycloheptane", "heptylcycloheptane"));
  273. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  274. new CyclicOrganicMoleculeBuilder(9)
  275. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createAlkyl(6)), "1-hexylcyclononane", "hexylcyclononane"));
  276. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  277. new CyclicOrganicMoleculeBuilder(5)
  278. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1-bromocyclopentane", "bromocyclopentane"));
  279. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  280. new CyclicOrganicMoleculeBuilder(4)
  281. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "cyclobutan-1-ol", "cyclobutanol"));
  282. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  283. new CyclicOrganicMoleculeBuilder(9)
  284. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "cyclononan-1-ol", "cyclononanol"));
  285. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  286. new CyclicOrganicMoleculeBuilder(5)
  287. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "cyclopentan-1-one", "cyclopentanone"));
  288. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MONOSUBSTITUTED_RING,
  289. new CyclicOrganicMoleculeBuilder(6)
  290. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "cyclohexan-1-one", "cyclohexanone"));
  291.  
  292.  
  293. // Naming linear/branching alkanes with one low-priority substituent on the main chain
  294. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  295. new LinearOrganicMoleculeBuilder(3)
  296. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "2-methylpropane", "isobutane"));
  297. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  298. new LinearOrganicMoleculeBuilder(1)
  299. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE)), "1-chloromethane", "chloromethane"));
  300. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  301. new LinearOrganicMoleculeBuilder(5)
  302. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(2)), "3-ethylpentane"));
  303. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  304. new LinearOrganicMoleculeBuilder(4)
  305. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  306. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1-bromohexane"));
  307. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  308. new LinearOrganicMoleculeBuilder(4)
  309. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "2-methylbutane"));
  310. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  311. new LinearOrganicMoleculeBuilder(3)
  312. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(2)), "2-methylbutane"));
  313. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  314. new LinearOrganicMoleculeBuilder(4)
  315. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "2-methylbutane"));
  316. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  317. new LinearOrganicMoleculeBuilder(9)
  318. .addSubstituent(7, OrganicMoleculeBuilder.Substituent.createAlkyl(2)), "3-methyldecane"));
  319. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  320. new LinearOrganicMoleculeBuilder(7)
  321. .addSubstituent(6, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  322. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlkyl(3)), "5-propylnonane"));
  323. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  324. new LinearOrganicMoleculeBuilder(7)
  325. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(4)), "4-propyloctane"));
  326. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  327. new LinearOrganicMoleculeBuilder(6)
  328. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "3-fluorohexane"));
  329. // ^^^ ABOVE: low-priority substituents
  330. // vvv BELOW: high-priority substituents
  331. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  332. new LinearOrganicMoleculeBuilder(5)
  333. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "pentan-3-one"));
  334. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  335. new LinearOrganicMoleculeBuilder(1)
  336. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "methan-1-ol", "methanol"));
  337. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  338. new LinearOrganicMoleculeBuilder(2)
  339. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "ethan-1-ol", "ethanol"));
  340. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  341. new LinearOrganicMoleculeBuilder(2)
  342. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol()), "ethan-1-ol", "ethanol"));
  343. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  344. new LinearOrganicMoleculeBuilder(3)
  345. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol()), "propan-2-ol", "isopropanol"));
  346. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  347. new LinearOrganicMoleculeBuilder(3)
  348. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "propan-1-ol"));
  349. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  350. new LinearOrganicMoleculeBuilder(6)
  351. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "hexan-2-one"));
  352. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  353. new LinearOrganicMoleculeBuilder(6)
  354. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "hexan-2-one"));
  355. // ^^^ ABOVE: high-priority substituents
  356. // vvv BELOW: end groups
  357. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  358. new LinearOrganicMoleculeBuilder(4)
  359. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "butanal"));
  360. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  361. new LinearOrganicMoleculeBuilder(3)
  362. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "propanal"));
  363. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  364. new LinearOrganicMoleculeBuilder(1)
  365. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "methanal", "formaldehyde"));
  366. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  367. new LinearOrganicMoleculeBuilder(10)
  368. .addSubstituent(9, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "decanal"));
  369. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  370. new LinearOrganicMoleculeBuilder(6)
  371. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "hexanal"));
  372. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  373. new LinearOrganicMoleculeBuilder(1)
  374. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  375. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "methanoic acid", "formic acid"));
  376. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  377. new LinearOrganicMoleculeBuilder(2)
  378. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  379. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "ethanoic acid", "acetic acid"));
  380. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  381. new LinearOrganicMoleculeBuilder(2)
  382. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  383. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol()), "ethanoic acid", "acetic acid"));
  384. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  385. new LinearOrganicMoleculeBuilder(8)
  386. .addSubstituent(7, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  387. .addSubstituent(7, OrganicMoleculeBuilder.Substituent.createAlcohol()), "octanoic acid"));
  388. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  389. new LinearOrganicMoleculeBuilder(5)
  390. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  391. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "pentanoic acid"));
  392. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  393. new LinearOrganicMoleculeBuilder(3)
  394. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  395. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "propanoic acid"));
  396. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.SINGLE_SUBSTITUENT_LINEAR,
  397. new LinearOrganicMoleculeBuilder(4)
  398. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  399. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlcohol()), "butanoic acid"));
  400.  
  401. // Naming structures with multiple substituents but no difficult priority tiebreaks
  402. // This is extra credit!
  403. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  404. new LinearOrganicMoleculeBuilder(5)
  405. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  406. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "2,4-dimethylpentane"));
  407. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  408. new LinearOrganicMoleculeBuilder(3)
  409. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  410. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "2,2-dimethylpropane", "neopentane"));
  411. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  412. new LinearOrganicMoleculeBuilder(6)
  413. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  414. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(2)), "3-ethyl-2-methylhexane"));
  415. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  416. new LinearOrganicMoleculeBuilder(2)
  417. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  418. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol()), "ethane-1,2-diol"));
  419. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  420. new LinearOrganicMoleculeBuilder(1)
  421. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  422. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  423. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  424. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()), "methane-1,1,1,1-tetrol", "methanetetrol"));
  425. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  426. new LinearOrganicMoleculeBuilder(4)
  427. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  428. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "butane-2,3-dione"));
  429. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  430. new LinearOrganicMoleculeBuilder(8)
  431. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  432. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  433. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  434. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  435. .addSubstituent(6, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "octane-2,3,4,5,6-pentone"));
  436. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  437. new LinearOrganicMoleculeBuilder(8)
  438. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  439. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  440. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  441. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  442. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "4-ethyl-2,3,5,6-tetramethyloctane"));
  443. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  444. new LinearOrganicMoleculeBuilder(6)
  445. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  446. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlkyl(2)), "4-ethyl-3-methylheptane"));
  447. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  448. new LinearOrganicMoleculeBuilder(8)
  449. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  450. .addSubstituent(6, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  451. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(3)), "6-bromo-2-fluoro-5-propyloctane"));
  452. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  453. new LinearOrganicMoleculeBuilder(2)
  454. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  455. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "1,2-difluoroethane"));
  456. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  457. new LinearOrganicMoleculeBuilder(6)
  458. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  459. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  460. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1-bromo-3,4-diethylhexane"));
  461. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  462. new LinearOrganicMoleculeBuilder(4)
  463. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  464. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  465. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  466. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE)), "2-bromo-3-chloro-1-fluoro-2-methylbutane"));
  467. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  468. new CyclicOrganicMoleculeBuilder(4)
  469. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  470. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  471. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  472. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "1,2,3,4-tetramethylcyclobutane"));
  473. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  474. new CyclicOrganicMoleculeBuilder(9)
  475. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  476. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(8)), "1-chloro-1-octylcyclononane"));
  477. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  478. new CyclicOrganicMoleculeBuilder(6)
  479. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(4))
  480. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlkyl(4)), "1,4-dibutylcyclohexane"));
  481. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  482. new CyclicOrganicMoleculeBuilder(3)
  483. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  484. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol())
  485. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol())
  486. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  487. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol())
  488. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "cyclopropane-1,1,2,2,3,3-hexol"));
  489. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.MULTIPLE_SUBSTITUENTS,
  490. new CyclicOrganicMoleculeBuilder(5)
  491. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  492. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  493. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  494. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  495. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "cyclopentane-1,2,3,4,5-pentone"));
  496.  
  497. // Naming structures with multiple substituents requiring priority tiebreaks
  498. // This is extra credit and very difficult!
  499. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  500. new LinearOrganicMoleculeBuilder(2)
  501. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  502. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  503. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "2-bromo-2-chloroethan-1-ol"));
  504. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  505. new LinearOrganicMoleculeBuilder(4)
  506. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  507. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlcohol())
  508. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  509. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "4-methylpentanoic acid"));
  510. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  511. new LinearOrganicMoleculeBuilder(7)
  512. .addSubstituent(6, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  513. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "5-bromoheptanal"));
  514. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  515. new LinearOrganicMoleculeBuilder(4)
  516. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol())
  517. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "4-fluorobutan-2-ol"));
  518. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  519. new LinearOrganicMoleculeBuilder(3)
  520. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  521. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(5))
  522. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "2-pentylpropane-1,3-diol"));
  523. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  524. new LinearOrganicMoleculeBuilder(3)
  525. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  526. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  527. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  528. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "2-bromo-1,1,3-trifluoropropane"));
  529. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  530. new LinearOrganicMoleculeBuilder(4)
  531. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  532. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  533. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  534. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  535. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlcohol()), "3,4-difluoro-3-methylbutanoic acid"));
  536. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  537. new LinearOrganicMoleculeBuilder(3)
  538. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  539. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE)), "1-bromo-3-chloropropane"));
  540. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  541. new LinearOrganicMoleculeBuilder(3)
  542. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  543. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE)), "1-bromo-3-chloropropane"));
  544. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  545. new LinearOrganicMoleculeBuilder(3)
  546. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  547. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  548. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "3-bromo-1-chloropropan-1-ol"));
  549. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  550. new LinearOrganicMoleculeBuilder(2)
  551. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  552. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  553. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  554. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "1,2-dibromo-1-chloro-2-fluoroethane"));
  555. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  556. new LinearOrganicMoleculeBuilder(2)
  557. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  558. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  559. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  560. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "1,2-dibromo-1-chloro-2-fluoroethane"));
  561. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  562. new LinearOrganicMoleculeBuilder(4)
  563. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  564. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  565. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  566. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "4,4,4-trichlorobutan-2-one"));
  567. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  568. new LinearOrganicMoleculeBuilder(5)
  569. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  570. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  571. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(3))
  572. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "4-bromo-3-methyl-2-propylpentanal"));
  573. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  574. new CyclicOrganicMoleculeBuilder(3)
  575. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol())
  576. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "cyclopropane-1,2-diol"));
  577. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  578. new CyclicOrganicMoleculeBuilder(3)
  579. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol())
  580. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol()), "cyclopropane-1,2-diol"));
  581. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  582. new CyclicOrganicMoleculeBuilder(5)
  583. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  584. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1,3-dibromocyclopentane"));
  585. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  586. new CyclicOrganicMoleculeBuilder(6)
  587. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  588. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1-bromo-2-methylcyclohexane"));
  589. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  590. new CyclicOrganicMoleculeBuilder(6)
  591. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  592. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  593. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "2-bromo-1,1-diethylcyclohexane"));
  594. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  595. new CyclicOrganicMoleculeBuilder(5)
  596. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol())
  597. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(5)), "3-pentylcyclopentan-1-ol"));
  598. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  599. new CyclicOrganicMoleculeBuilder(5)
  600. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(3))
  601. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlcohol())
  602. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlcohol()), "4-propylcyclopentane-1,2-diol"));
  603. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  604. new CyclicOrganicMoleculeBuilder(4)
  605. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  606. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  607. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  608. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(1)), "2,2-dibromo-4-methylcyclobutan-1-one"));
  609. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  610. new CyclicOrganicMoleculeBuilder(4)
  611. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  612. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  613. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  614. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  615. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()), "2,4-dibromo-2-methylcyclobutane-1,3-dione"));
  616. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  617. new CyclicOrganicMoleculeBuilder(7)
  618. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  619. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  620. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  621. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  622. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "2-chloro-7-ethyl-7-fluorocycloheptane-1,4-dione"));
  623. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  624. new CyclicOrganicMoleculeBuilder(8)
  625. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  626. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  627. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol())
  628. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlcohol())
  629. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createAlcohol())
  630. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createAlcohol())
  631. .addSubstituent(6, OrganicMoleculeBuilder.Substituent.createAlkyl(3)), "6-ethyl-6-methyl-8-propylcyclooctane-1,1,3,5-tetrol"));
  632. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  633. new CyclicOrganicMoleculeBuilder(3)
  634. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  635. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  636. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1-bromo-2-chloro-3-fluorocyclopropane"));
  637. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  638. new CyclicOrganicMoleculeBuilder(3)
  639. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  640. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  641. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)), "1-bromo-2-chloro-3-fluorocyclopropane"));
  642. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  643. new CyclicOrganicMoleculeBuilder(3)
  644. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  645. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  646. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  647. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "1,2-dibromo-1-chloro-3-fluorocyclopropane"));
  648. namingTestCases.add(new MoleculeNamingTestInput(MoleculeNamingTestDifficulty.PRIORITY_TIEBREAK,
  649. new CyclicOrganicMoleculeBuilder(3)
  650. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE))
  651. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE))
  652. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE))
  653. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol())
  654. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)), "2,3-dibromo-2-chloro-1-fluorocyclopropan-1-ol"));
  655. }
  656.  
  657. /*
  658.  
  659. ^^^^^^^^^^^^^^^^^^^
  660. ABOVE: GRADED TESTS
  661.  
  662. The remaining tests are to help you test your helper functions.
  663. They are not graded; you may comment them out if you know what you're doing
  664. and your set of helper functions is incompatible with ours.
  665.  
  666. Some of these tests rely on the order in which OrganicMoleculeBuilder
  667. attaches neighbors to each atom. You should not do this in your code;
  668. it's finicky and not guaranteed to work. (In general, relying on undocumented
  669. behavior of other people's code is bad.)
  670.  
  671. Note that these don't necessarily check functionality required for getting extra credit -
  672. for that, you're on your own.
  673.  
  674. BELOW: HELPER TESTS
  675. vvvvvvvvvvvvvvvvvvv
  676.  
  677. */
  678.  
  679. /** getAllAtoms returns a collection of all the atoms in the molecule */
  680. @Test(timeOut = HELPER_TEST_TIMEOUT)
  681. public void helpGetAllAtoms() {
  682. MoleculeAnalyzer methane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(1).build());
  683. Assert.assertEquals(methane.getAllAtoms().stream().distinct().count(), 5, "findAllAtoms failed on a 1-carbon molecule");
  684.  
  685. MoleculeAnalyzer butane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(4).build());
  686. Assert.assertEquals(butane.getAllAtoms().stream().distinct().count(), 14, "findAllAtoms failed on a 4-carbon molecule");
  687.  
  688. MoleculeAnalyzer isopropanol = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  689. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol()).build());
  690. Assert.assertEquals(isopropanol.getAllAtoms().stream().distinct().count(), 12, "findAllAtoms failed on a chain with a substituent");
  691.  
  692. MoleculeAnalyzer ethoxide = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(2)
  693. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol(0)).build());
  694. Assert.assertEquals(ethoxide.getAllAtoms().stream().distinct().count(), 8, "findAllAtoms failed on a charged molecule");
  695.  
  696. MoleculeAnalyzer cyclopropane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3).build());
  697. Assert.assertEquals(cyclopropane.getAllAtoms().stream().distinct().count(), 9, "findAllAtoms failed on a cyclic molecule");
  698.  
  699. MoleculeAnalyzer ethylcyclobutane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(4)
  700. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(2)).build());
  701. Assert.assertEquals(ethylcyclobutane.getAllAtoms().stream().distinct().count(), 18, "findAllAtoms failed on a substituted cyclic molecule");
  702. }
  703.  
  704. /** getTips finds all the tip carbons in the molecule */
  705. @Test(timeOut = HELPER_TEST_TIMEOUT)
  706. public void helpGetTips() {
  707. List<BondedAtom> ethaneTips = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(2).build()).getTips();
  708. Assert.assertEquals(ethaneTips.size(), 2, "getTips didn't find the tips of a 2-carbon molecule");
  709. Assert.assertTrue(ethaneTips.get(0).isCarbon() && ethaneTips.get(1).isCarbon(), "getTips returned non-carbon atoms");
  710.  
  711. BondedAtom propanal = new LinearOrganicMoleculeBuilder(3)
  712. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()).build();
  713. List<BondedAtom> propaneTips = new MoleculeAnalyzer(propanal).getTips();
  714. Assert.assertEquals(propaneTips.size(), 2, "getTips didn't find the tips of a substituted 3-carbon molecule");
  715. Assert.assertTrue(propaneTips.contains(propanal), "getTips missed the first backbone carbon");
  716. Assert.assertTrue(propaneTips.contains(Objects.requireNonNull(propanal.getConnectedAtom(1)).getConnectedAtom(1)), "getTips missed the last backbone carbon");
  717.  
  718. List<BondedAtom> methaneTips = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(1).build()).getTips();
  719. Assert.assertEquals(methaneTips.size(), 1, "getTips didn't recognize a lone carbon as a tip");
  720.  
  721. BondedAtom isopentane = new LinearOrganicMoleculeBuilder(4)
  722. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build();
  723. List<BondedAtom> isopentaneTips = new MoleculeAnalyzer(isopentane).getTips();
  724. Assert.assertEquals(isopentaneTips.stream().distinct().count(), 3, "getTips failed on a branched linear molecule");
  725. final String isopentaneFail = "getTips misidentified the tips of 2-methylbutane";
  726. Assert.assertTrue(isopentaneTips.contains(isopentane), isopentaneFail);
  727. Assert.assertTrue(isopentaneTips.contains(Objects.requireNonNull(Objects.requireNonNull(isopentane.getConnectedAtom(1)).getConnectedAtom(1)).getConnectedAtom(1)), isopentaneFail);
  728. Assert.assertTrue(isopentaneTips.contains(Objects.requireNonNull(Objects.requireNonNull(isopentane.getConnectedAtom(1)).getConnectedAtom(1)).getConnectedAtom(2)), isopentaneFail);
  729. List<BondedAtom> cyclohexaneTips = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(6).build()).getTips();
  730.  
  731. Assert.assertEquals(cyclohexaneTips.size(), 0, "getTips found tips on an unsubstituted ring");
  732. List<BondedAtom> methylcyclopropaneTips = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3)
  733. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build()).getTips();
  734.  
  735. Assert.assertEquals(methylcyclopropaneTips.size(), 1, "getTips missed the tip of a substituted ring");
  736. Assert.assertFalse(Objects.requireNonNull(methylcyclopropaneTips.get(0).getConnectedAtom(1)).isCarbon(), "getTips misidentified the tip of a substituted ring");
  737. }
  738.  
  739. /** findPath finds the path from one atom to another in a linear molecule */
  740. @Test(timeOut = HELPER_TEST_TIMEOUT)
  741. public void helpFindPath() {
  742. BondedAtom ethane = new LinearOrganicMoleculeBuilder(2).build();
  743. List<BondedAtom> ethanePath = new MoleculeAnalyzer(ethane).findPath(ethane, ethane.getConnectedAtom(1));
  744. Assert.assertEquals(ethanePath.size(), 2, "findPath found a path of the wrong length on ethane");
  745. Assert.assertSame(ethanePath.get(0), ethane, "findPath's path on ethane started at the wrong atom");
  746. Assert.assertSame(ethanePath.get(1), ethane.getConnectedAtom(1), "findPath's path on ethane ended at the wrong atom");
  747.  
  748. BondedAtom isobutane = new LinearOrganicMoleculeBuilder(3)
  749. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build();
  750. List<BondedAtom> isobutanePath = new MoleculeAnalyzer(isobutane).findPath(Objects.requireNonNull(isobutane.getConnectedAtom(1)).getConnectedAtom(2), Objects.requireNonNull(isobutane.getConnectedAtom(1)).getConnectedAtom(1));
  751. Assert.assertEquals(isobutanePath.size(), 3, "findPath found a path of the wrong length from one tip of 2-methylpropane to another");
  752. Assert.assertSame(isobutanePath.get(0), Objects.requireNonNull(isobutane.getConnectedAtom(1)).getConnectedAtom(2), "findPath's path on 2-methylpropane started at the wrong atom");
  753. Assert.assertSame(isobutanePath.get(1), isobutane.getConnectedAtom(1), "findPath's path on 2-methylpropane was incorrect");
  754. Assert.assertSame(isobutanePath.get(2), Objects.requireNonNull(isobutane.getConnectedAtom(1)).getConnectedAtom(1), "findPath's path on 2-methylpropane ended at the wrong atom");
  755. }
  756.  
  757. /** isCyclic checks whether the molecule contains a cycle */
  758. @Test(timeOut = HELPER_TEST_TIMEOUT)
  759. public void helpIsCyclic() {
  760. MoleculeAnalyzer propane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3).build());
  761. Assert.assertFalse(propane.isRing(), "isCyclic misidentified a linear molecule");
  762.  
  763. MoleculeAnalyzer methane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(1).build());
  764. Assert.assertFalse(methane.isRing(), "isCyclic misidentified a one-carbon molecule");
  765.  
  766. MoleculeAnalyzer isobutane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  767. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build());
  768. Assert.assertFalse(isobutane.isRing(), "isCyclic misidentified a branched linear molecule");
  769.  
  770. MoleculeAnalyzer cyclopropane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3).build());
  771. Assert.assertTrue(cyclopropane.isRing(), "isCyclic misidentified a small cyclic molecule");
  772.  
  773. MoleculeAnalyzer cyclooctane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(8).build());
  774. Assert.assertTrue(cyclooctane.isRing(), "isCyclic misidentified a large cyclic molecule");
  775.  
  776. MoleculeAnalyzer ethylcyclobutane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(4)
  777. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(2)).build());
  778. Assert.assertTrue(ethylcyclobutane.isRing(), "isCyclic misidentified a cyclic molecule with a substituent");
  779.  
  780. MoleculeAnalyzer mess = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(7)
  781. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  782. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  783. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createCarbonyl())
  784. .addSubstituent(6, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.CHLORINE)).build());
  785. Assert.assertTrue(mess.isRing(), "isCyclic misidentified a complicated cyclic molecule");
  786. }
  787.  
  788. /** getRing gets a list of the carbon atoms in the cycle */
  789. @Test(timeOut = HELPER_TEST_TIMEOUT)
  790. public void helpGetRing() {
  791. MoleculeAnalyzer cyclopentane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(5).build());
  792. List<BondedAtom> cyclopentaneRing = cyclopentane.getRing();
  793. Assert.assertNotNull(cyclopentaneRing, "getRing didn't find a ring on a simple cyclic molecule");
  794. Assert.assertEquals(cyclopentaneRing.size(), 5, "getRing found a ring of the wrong size on a simple cyclic molecule");
  795.  
  796. MoleculeAnalyzer cyclobutanone = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(4)
  797. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createCarbonyl()).build());
  798. List<BondedAtom> cyclobutanoneRing = cyclobutanone.getRing();
  799. Assert.assertNotNull(cyclobutanoneRing, "getRing didn't find a ring on a cyclic molecule with a substituent");
  800. Assert.assertEquals(cyclobutanoneRing.size(), 4, "getRing found a ring of the wrong size on a cyclic molecule with a substituent");
  801.  
  802. MoleculeAnalyzer tripropylcyclopropane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3)
  803. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlkyl(3))
  804. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(3))
  805. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(3)).build());
  806. List<BondedAtom> tripropylcyclopropaneRing = tripropylcyclopropane.getRing();
  807. Assert.assertNotNull(tripropylcyclopropaneRing, "getRing didn't find a ring on a cyclic molecule with alkyl substituents");
  808. Assert.assertEquals(tripropylcyclopropaneRing.size(), 3, "getRing found a ring of the wrong size on a cyclic molecule with alkyl substituents");
  809. }
  810.  
  811. /** getBackbones finds all possible backbones (paths between two tips) for a linear molecule */
  812. @Test(timeOut = HELPER_TEST_TIMEOUT)
  813. public void helpGetBackbones() {
  814. List<List<BondedAtom>> ethaneBackbones = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(2).build()).getBackbones();
  815. ethaneBackbones.forEach(lba -> lba.forEach(bondedAtom -> Assert.assertTrue(bondedAtom.isCarbon(), "getBackbones included non-carbon atoms in the backbone")));
  816. Assert.assertEquals(ethaneBackbones.size(), 2, "getBackbones didn't return both directions for traversing a 2-carbon molecule");
  817.  
  818. List<List<BondedAtom>> isopropanolBackbones = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  819. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlcohol()).build()).getBackbones();
  820. Assert.assertEquals(isopropanolBackbones.size(), 2, "getBackbones failed on a substituted 3-carbon molecule");
  821.  
  822. List<List<BondedAtom>> isobutaneBackbones = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  823. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build()).getBackbones();
  824. Assert.assertEquals(isobutaneBackbones.size(), 6, "getBackbones failed on a singly-branched molecule");
  825.  
  826. List<List<BondedAtom>> trimethylbutaneBackbones = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(4)
  827. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  828. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  829. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build()).getBackbones();
  830. Assert.assertEquals(trimethylbutaneBackbones.size(), 20, "getBackbones failed on a highly branched molecule");
  831. }
  832.  
  833. /** getLinearBackbone finds the carbons in a linear molecule's backbone (longest chain, under most circumstances) */
  834. @Test(timeOut = HELPER_TEST_TIMEOUT)
  835. public void helpGetLinearBackbone() {
  836. MoleculeAnalyzer methane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(1).build());
  837. List<BondedAtom> methaneBackbone = methane.getLinearBackbone();
  838. Assert.assertEquals(methaneBackbone.size(), 1, "getLinearBackbone didn't find the backbone of a one-carbon molecule");
  839. Assert.assertTrue(methaneBackbone.get(0).isCarbon(), "getLinearBackbone selected a non-carbon atom as the backbone for a one-carbon molecule");
  840.  
  841. MoleculeAnalyzer ethane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(2).build());
  842. Assert.assertEquals(ethane.getLinearBackbone().size(), 2, "getLinearBackbone didn't find the backbone of a two-carbon molecule");
  843.  
  844. MoleculeAnalyzer ethanol = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(2)
  845. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createAlcohol()).build());
  846. Assert.assertEquals(ethanol.getLinearBackbone().size(), 2, "getLinearBackbone misidentified the backbone of an unbranched substituted molecule");
  847.  
  848. MoleculeAnalyzer bromopropane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  849. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)).build());
  850. List<BondedAtom> bromopropaneBackbone = bromopropane.getLinearBackbone();
  851. Assert.assertEquals(bromopropaneBackbone.size(), 3, "getLinearBackbone misidentified the backbone of an unbranched substituted three-carbon molecule");
  852. for (BondedAtom a : bromopropaneBackbone) {
  853. Assert.assertEquals(a.getElement().getSymbol(), ChemicalElement.CARBON.getSymbol(), "getLinearBackbone included a non-carbon atom in the backbone");
  854. }
  855.  
  856. MoleculeAnalyzer methylbutane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  857. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(2)).build());
  858. Assert.assertEquals(methylbutane.getLinearBackbone().size(), 4, "getLinearBackbone misidentified the backbone of a branched molecule with 3 tips");
  859.  
  860. MoleculeAnalyzer neopentane = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(3)
  861. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  862. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build());
  863. Assert.assertEquals(neopentane.getLinearBackbone().size(), 3, "getLinearBackbone misidentified the backbone of a symmetrical branched molecule with 4 tips");
  864.  
  865. MoleculeAnalyzer manyTips = new MoleculeAnalyzer(new LinearOrganicMoleculeBuilder(6)
  866. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  867. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createAlkyl(1))
  868. .addSubstituent(3, OrganicMoleculeBuilder.Substituent.createAlkyl(2))
  869. .addSubstituent(4, OrganicMoleculeBuilder.Substituent.createAlkyl(5))
  870. .addSubstituent(5, OrganicMoleculeBuilder.Substituent.createAlkyl(3)).build());
  871. Assert.assertEquals(manyTips.getLinearBackbone().size(), 10, "getLinearBackbone misidentified the backbone of a molecule with 6 tips");
  872. }
  873.  
  874. /** rotateRing rotates and/or flips the ring such that a substituent, if present, is at the first position */
  875. @Test(timeOut = HELPER_TEST_TIMEOUT, dependsOnMethods = "helpGetRing")
  876. public void helpRotateRing() {
  877. MoleculeAnalyzer cyclopropane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3).build());
  878. List<BondedAtom> cyclopropaneRing = cyclopropane.getRing();
  879. Assert.assertEqualsNoOrder(cyclopropane.rotateRing(cyclopropaneRing).toArray(), cyclopropaneRing.toArray(), "rotateRing didn't preserve the atoms in the ring");
  880.  
  881. MoleculeAnalyzer bromocyclopropane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3)
  882. .addSubstituent(0, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.BROMINE)).build());
  883. List<BondedAtom> bromocyclopropaneRing = bromocyclopropane.getRing();
  884. List<BondedAtom> bromocyclopropaneRotated = bromocyclopropane.rotateRing(bromocyclopropaneRing);
  885. Assert.assertEqualsNoOrder(bromocyclopropaneRotated.toArray(), bromocyclopropaneRing.toArray(), "rotateRing didn't preserve the atoms in a substituted ring");
  886. Assert.assertSame(Objects.requireNonNull(bromocyclopropaneRotated.get(0).getConnectedAtom(0)).getElement(), ChemicalElement.BROMINE, "rotateRing unnecessarily rotated an already-correct substituted ring");
  887.  
  888. MoleculeAnalyzer fluorocyclopropane = new MoleculeAnalyzer(new CyclicOrganicMoleculeBuilder(3)
  889. .addSubstituent(1, OrganicMoleculeBuilder.Substituent.createHalogen(ChemicalElement.FLUORINE)).build());
  890. List<BondedAtom> fluorocyclopropaneRing = fluorocyclopropane.getRing();
  891. List<BondedAtom> fluorocyclopropaneRotated = fluorocyclopropane.rotateRing(fluorocyclopropaneRing);
  892. Assert.assertEqualsNoOrder(fluorocyclopropaneRing.toArray(), fluorocyclopropaneRing.toArray(), "rotateRing didn't preserve the atoms in a substituted ring with necessary rotation");
  893. Assert.assertSame(Objects.requireNonNull(fluorocyclopropaneRotated.get(0).getConnectedAtom(2)).getElement(), ChemicalElement.FLUORINE, "rotateRing didn't rotate a substituted ring correctly");
  894.  
  895. BondedAtom methylcylobutaneMol = new CyclicOrganicMoleculeBuilder(4)
  896. .addSubstituent(2, OrganicMoleculeBuilder.Substituent.createAlkyl(1)).build();
  897. MoleculeAnalyzer methylcyclobutane = new MoleculeAnalyzer(methylcylobutaneMol);
  898. List<BondedAtom> methylcyclobutaneRing = methylcyclobutane.getRing();
  899. List<BondedAtom> methylcyclobutaneRotated = methylcyclobutane.rotateRing(methylcyclobutaneRing);
  900. Assert.assertFalse(methylcyclobutaneRotated.contains(Objects.requireNonNull(Objects.requireNonNull(methylcylobutaneMol.getConnectedAtom(1)).getConnectedAtom(1)).getConnectedAtom(2)), "rotateRing included a methyl substituent in the ring");
  901. Assert.assertEqualsNoOrder(methylcyclobutaneRotated.toArray(), methylcyclobutaneRing.toArray(), "rotateRing didn't preserve the atoms in a methylated ring");
  902. Assert.assertSame(methylcyclobutaneRotated.get(0), Objects.requireNonNull(methylcylobutaneMol.getConnectedAtom(1)).getConnectedAtom(1), "rotateRing didn't rotate a methylated ring correctly");
  903. }
  904. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement