ChadoFieldGetValuesListTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <?php
  2. namespace Tests\tripal_chado\fields;
  3. use StatonLab\TripalTestSuite\DBTransaction;
  4. use StatonLab\TripalTestSuite\TripalTestCase;
  5. /**
  6. * Test ChadoField->getValueList() Method.
  7. */
  8. class ChadoFieldGetValuesListTest extends TripalTestCase {
  9. // Uncomment to auto start and rollback db transactions per test method.
  10. use DBTransaction;
  11. // Stores a list of field instances to be tested including their storage method and instance info.
  12. private $field_list = NULL;
  13. /**
  14. * Test getValueList for fields based on columns in the base table.
  15. *
  16. * @dataProvider getBaseFields
  17. *
  18. * @group fields
  19. * @group getValueList
  20. */
  21. public function testBaseTableColumns($field_name, $bundle_name, $info) {
  22. include_once(drupal_get_path('tripal_chado', 'module') . '/includes/TripalFields/ChadoField.inc');
  23. // Construct the Field instance we want the values for.
  24. // Specifying "ChadoField" here ensures we are only testing our
  25. // implementation of getValueList() and not the custom version for any
  26. // given field.
  27. // YOU SHOULD TEST CUSTOM FIELD IMPLEMENTATIONS SEPARATELY.
  28. $instance = new \ChadoField($info['field_info'], $info['instance_info']);
  29. // Retrieve the values.
  30. // $values will be an array containing the distinct set of values for this field instance.
  31. $values = $instance->getValueList(array('limit' => 5));
  32. // Ensure we have values returned!
  33. $this->assertTrue(
  34. is_array($values),
  35. t(
  36. 'No values returned for @field_name (bundle: @bundle_name, bundle base table: @bundle_base_table, chado table: @chado_table, chado column: @chado_column).',
  37. array(
  38. '@field_name' => $field_name,
  39. '@bundle_name' => $bundle_name,
  40. '@bundle_base_table' => $info['bundle_base_table'],
  41. '@chado_table' => $info['instance_info']['settings']['chado_table'],
  42. '@chado_column' => $info['instance_info']['settings']['chado_column'],
  43. )
  44. )
  45. );
  46. // Ensure there are no more then 5 as specified in the limit above.
  47. $this->assertLessThanOrEqual(5, sizeof($values),
  48. t('Returned too many results for @field_name.', array('@field_name' => $field_name)));
  49. }
  50. /**
  51. * DataProvider: a list of fields who store their data in the base table of a bundle.
  52. *
  53. * Each element describes a field instance and consists of:
  54. * - the machine name of the field (e.g. obi__organism).
  55. * - the machine name of the bundle (e.g. bio_data_17).
  56. * - an array of additional information including:
  57. * - instance_info: information about the field instance.
  58. * - field_info: information about the field.
  59. * - bundle: the TripalBundle object.
  60. * - bundle_base_table: if applicable, the chado base table the bundle stores it's data in.
  61. * - base_schema: the Tripal Schema array for the bundle_base_table.
  62. */
  63. public function getBaseFields() {
  64. // Retrieve a list of fields to test.
  65. // Note: this list is cached to improve performance.
  66. $fields = $this->retrieveFieldList();
  67. return $fields['field_chado_storage']['base'];
  68. }
  69. /**
  70. * Test for fields based on columns in the base table that are also foreign keys.
  71. *
  72. * @dataProvider getBaseFkFields
  73. *
  74. * @group fields
  75. * @group getValueList
  76. */
  77. public function testBaseTableForeignKey($field_name, $bundle_name, $info) {
  78. include_once(drupal_get_path('tripal_chado', 'module') . '/includes/TripalFields/ChadoField.inc');
  79. // Construct the Field instance we want the values for.
  80. // Specifying "ChadoField" here ensures we are only testing our
  81. // implementation of getValueList() and not the custom version for any
  82. // given field.
  83. // YOU SHOULD TEST CUSTOM FIELD IMPLEMENTATIONS SEPARATELY.
  84. $instance = new \ChadoField($info['field_info'], $info['instance_info']);
  85. // Retrieve the values using defaults.
  86. // $values will be an array containing the distinct set of values for this field instance.
  87. $values = $instance->getValueList(array('limit' => 5));
  88. // Ensure we have values returned!
  89. $this->assertTrue(
  90. is_array($values),
  91. t(
  92. 'No values returned for @field_name with no label string set (bundle: @bundle_name, bundle base table: @bundle_base_table, chado table: @chado_table, chado column: @chado_column).',
  93. array(
  94. '@field_name' => $field_name,
  95. '@bundle_name' => $bundle_name,
  96. '@bundle_base_table' => $info['bundle_base_table'],
  97. '@chado_table' => $info['instance_info']['settings']['chado_table'],
  98. '@chado_column' => $info['instance_info']['settings']['chado_column'],
  99. )
  100. )
  101. );
  102. // Ensure there are no more then 5 as specified in the limit above.
  103. $this->assertLessThanOrEqual(5, sizeof($values),
  104. t('Returned too many results for @field_name.', array('@field_name' => $field_name)));
  105. // @todo Ensure it works with a label string set.
  106. }
  107. /**
  108. * DataProvider: a list of fields who store their data in the base table of a bundle.
  109. *
  110. * Each element describes a field instance and consists of:
  111. * - the machine name of the field (e.g. obi__organism).
  112. * - the machine name of the bundle (e.g. bio_data_17).
  113. * - an array of additional information including:
  114. * - instance_info: information about the field instance.
  115. * - field_info: information about the field.
  116. * - bundle: the TripalBundle object.
  117. * - bundle_base_table: if applicable, the chado base table the bundle stores it's data in.
  118. * - base_schema: the Tripal Schema array for the bundle_base_table.
  119. */
  120. public function getBaseFkFields() {
  121. // Retrieve a list of fields to test.
  122. // Note: this list is cached to improve performance.
  123. $fields = $this->retrieveFieldList();
  124. return $fields['field_chado_storage']['foreign key'];
  125. }
  126. /**
  127. * Test for fields based on tables besides the base one for the bundle.
  128. * CURRENTLY RETRIEVING VALUES FOR THESE TABLES IS NOT SUPPORTED.
  129. *
  130. * @dataProvider getNonBaseFields
  131. *
  132. * @group fields
  133. * @group getValueList
  134. */
  135. public function testNonBaseTable($field_name, $bundle_name, $info) {
  136. include_once(drupal_get_path('tripal_chado', 'module') . '/includes/TripalFields/ChadoField.inc');
  137. // Construct the Field instance we want the values for.
  138. // Specifying "ChadoField" here ensures we are only testing our
  139. // implementation of getValueList() and not the custom version for any
  140. // given field.
  141. // YOU SHOULD TEST CUSTOM FIELD IMPLEMENTATIONS SEPARATELY.
  142. $instance = new \ChadoField($info['field_info'], $info['instance_info']);
  143. // Supress tripal errors
  144. putenv("TRIPAL_SUPPRESS_ERRORS=TRUE");
  145. ob_start();
  146. try {
  147. // Retrieve the values.
  148. // $values will be an array containing the distinct set of values for this field instance.
  149. $values = $instance->getValueList(array('limit' => 5));
  150. // @todo Check that we got the correct warning message.
  151. // Currently we can't check this because we need to supress the error in order to keep it from printing
  152. // but once we do, we can't access it ;-P
  153. } catch (Exception $e) {
  154. $this->fail("Although we don't support values lists for $field_name, it still shouldn't produce an exception!");
  155. }
  156. // Clean the buffer and unset tripal errors suppression
  157. ob_end_clean();
  158. putenv("TRIPAL_SUPPRESS_ERRORS");
  159. $this->assertFalse($values, "We don't support retrieving values for $field_name since it doesn't store data in the base table.");
  160. }
  161. /**
  162. * DataProvider: a list of fields who store their data in the base table of a bundle.
  163. *
  164. * Each element describes a field instance and consists of:
  165. * - the machine name of the field (e.g. obi__organism).
  166. * - the machine name of the bundle (e.g. bio_data_17).
  167. * - an array of additional information including:
  168. * - instance_info: information about the field instance.
  169. * - field_info: information about the field.
  170. * - bundle: the TripalBundle object.
  171. * - bundle_base_table: if applicable, the chado base table the bundle stores it's data in.
  172. * - base_schema: the Tripal Schema array for the bundle_base_table.
  173. */
  174. public function getNonBaseFields() {
  175. // Retrieve a list of fields to test.
  176. // Note: this list is cached to improve performance.
  177. $fields = $this->retrieveFieldList();
  178. return $fields['field_chado_storage']['referring'];
  179. }
  180. /**
  181. * Returns a list of Fields sorted by their backend, etc. for use in tests.
  182. */
  183. private function retrieveFieldList() {
  184. if ($this->field_list === NULL) {
  185. $this->field_list = array();
  186. $bundles = field_info_instances('TripalEntity');
  187. foreach($bundles as $bundle_name => $fields) {
  188. $bundle = tripal_load_bundle_entity(array('name'=> $bundle_name));
  189. foreach ($fields as $field_name => $instance_info) {
  190. $bundle_base_table = $base_schema = NULL;
  191. // Load the field info.
  192. $field_info = field_info_field($field_name);
  193. $storage = $field_info['storage']['type'];
  194. // If this field stores it's data in chado...
  195. // Determine the relationship between this field and the bundle base table.
  196. $rel = NULL;
  197. if ($storage == 'field_chado_storage') {
  198. // We need to know the table this field stores it's data in.
  199. $bundle_base_table = $bundle->data_table;
  200. // and the schema for that table.
  201. $base_schema = chado_get_schema($bundle_base_table);
  202. // and the table this field stores it's data in.
  203. $field_table = $instance_info['settings']['chado_table'];
  204. $field_column = $instance_info['settings']['chado_column'];
  205. // By default we simply assume there is some relationship.
  206. $rel = 'referring';
  207. // If the field and bundle store their data in the same table
  208. // then it's either a "base" or "foreign key" relationship
  209. // based on the schema.
  210. if ($bundle_base_table == $field_table) {
  211. // We assume it's not a foreign key...
  212. $rel = 'base';
  213. // and then check the schema to see if we're wrong :-)
  214. foreach ($base_schema['foreign keys'] as $schema_info) {
  215. if (isset($schema_info['columns'][ $field_column ])) { $rel = 'foreign key'; }
  216. }
  217. }
  218. }
  219. $info = array(
  220. 'field_name' => $field_name,
  221. 'bundle_name' => $bundle_name,
  222. 'bundle' => $bundle,
  223. 'bundle_base_table' => $bundle_base_table,
  224. 'base_schema' => $base_schema,
  225. 'field_info' => $field_info,
  226. 'instance_info' => $instance_info,
  227. );
  228. $key = $bundle_name . '--' . $field_name;
  229. if ($rel) {
  230. $this->field_list[$storage][$rel][$key] = array(
  231. $field_name,
  232. $bundle_name,
  233. $info
  234. );
  235. }
  236. else {
  237. $this->field_list[$storage][$key] = array(
  238. $field_name,
  239. $bundle_name,
  240. $info
  241. );
  242. }
  243. }
  244. }
  245. }
  246. return $this->field_list;
  247. }
  248. }