Skip to content

Commit

Permalink
Implement rule builder rule to quickly grab group tag value.
Browse files Browse the repository at this point in the history
Should make it a lot easier to nested and filter on group tag values.
  • Loading branch information
jmchilton committed Jul 27, 2018
1 parent 4d83746 commit 5807230
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 5 deletions.
21 changes: 19 additions & 2 deletions client/galaxy/scripts/components/RuleCollectionBuilder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@
</select>
</label>
</rule-component>
<rule-component rule-type="add_column_group_tag_value"
:display-rule-type="displayRuleType"
:builder="this">
<label>
{{ l("Value") }}
<input type="text" v-model="addColumnGroupTagValueValue" />
</label>
<label>
{{ l("Default") }}
<input type="text" v-model="addColumnGroupTagValueDefault" />
</label>
</rule-component>
<rule-component rule-type="add_column_regex"
:display-rule-type="displayRuleType"
:builder="this">
Expand Down Expand Up @@ -286,6 +298,7 @@
<div class="dropdown-menu" role="menu">
<rule-target-component :builder="this" rule-type="add_column_basename" />
<rule-target-component :builder="this" rule-type="add_column_metadata" v-if="metadataOptions"/>
<rule-target-component :builder="this" rule-type="add_column_group_tag_value" v-if="hasTagsMetadata"/>
<rule-target-component :builder="this" rule-type="add_column_regex" />
<rule-target-component :builder="this" rule-type="add_column_concatenate" />
<rule-target-component :builder="this" rule-type="add_column_rownum" />
Expand Down Expand Up @@ -901,6 +914,8 @@ export default {
addColumnRegexGroupCount: null,
addColumnRegexType: "global",
addColumnMetadataValue: 0,
addColumnGroupTagValueValue: "",
addColumnGroupTagValueDefault: "",
addColumnConcatenateTarget0: 0,
addColumnConcatenateTarget1: 0,
addColumnRownumStart: 1,
Expand Down Expand Up @@ -1190,12 +1205,15 @@ export default {
} else if (this.elementsType == "datasets") {
metadataOptions["hid"] = _l("History ID (hid)");
metadataOptions["name"] = _l("Name");
metadataOptions["tags"] = _l("Tags");
} else {
metadataOptions = null;
}
return metadataOptions;
},
hasTagsMetadata() {
// TODO: allow for dataset, library_datasets also - here and just above in metadataOptions.
return this.elementsType == "collection_contents";
},
collectionType() {
let identifierColumns = [];
if (this.mappingAsDict.list_identifiers) {
Expand Down Expand Up @@ -1682,7 +1700,6 @@ export default {
if (collectionTypeLevelSepIndex === -1) {
// Flat collection at this depth.
// sources are the elements
// TOOD: right thing is probably this: data.push([]);
data.push([]);
const source = { identifiers: identifiers, dataset: elementObject, tags: elementObject.tags };
sources.push(source);
Expand Down
41 changes: 41 additions & 0 deletions client/galaxy/scripts/mvc/rules/rule-definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,47 @@ const RULES = {
return { data, columns };
}
},
add_column_group_tag_value: {
title: _l("Add Column from Group Tag Value"),
display: (rule, colHeaders) => {
return `Add column for value of group tag ${rule.value}.`;
},
init: (component, rule) => {
if (!rule) {
component.addColumnGroupTagValueValue = null;
component.addColumnGroupTagValueDefault = '';
} else {
component.addColumnGroupTagValueValue = rule.value;
component.addColumnGroupTagValueDefault = rule.default_value;
}
},
save: (component, rule) => {
rule.value = component.addColumnGroupTagValueValue;
rule.default_value = component.addColumnGroupTagValueDefault;
},
apply: (rule, data, sources, columns) => {
const ruleValue = rule.value;
const groupTagPrefix = `group:${ruleValue}:`;
const newRow = (row, index) => {
const newRow = row.slice();
const tags = sources[index]["tags"];
tags.sort();
let groupTagValue = rule.default_value;
for (let index in tags) {
const tag = tags[index];
if ( tag.indexOf(groupTagPrefix) == 0 ) {
groupTagValue = tag.substr(groupTagPrefix.length);
break;
}
}
newRow.push(groupTagValue);
return newRow;
};
data = data.map(newRow);
columns.push(NEW_COLUMN);
return { data, columns };
}
},
add_column_regex: {
title: _l("Using a Regular Expression"),
display: (rule, colHeaders) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy/managers/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ def __init_rule_data(self, elements, collection_type_description, parent_identif
identifiers = parent_identifiers + [element.element_identifier]
if not element.is_collection:
data.append([])
source = {"identifiers": identifiers, "dataset": element_object, "tags": element.make_tag_string_list()}
source = {"identifiers": identifiers, "dataset": element_object, "tags": element_object.make_tag_string_list()}
sources.append(source)
else:
child_collection_type_description = collection_type_description.child_collection_type_description()
Expand Down
29 changes: 29 additions & 0 deletions lib/galaxy/util/rules_dsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,34 @@ def sorted_tags(index):
return new_rows, sources


class AddColumnGroupTagValueRuleDefinition(BaseRuleDefinition):
rule_type = "add_column_group_tag_value"

def validate_rule(self, rule):
_ensure_rule_contains_keys(rule, {"value": six.string_types})

def apply(self, rule, data, sources):
rule_value = rule["value"]
tag_prefix = "group:%s:" % rule_value

new_rows = []
for index, row in enumerate(data):
group_tag_value = None
source = sources[index]
tags = source["tags"]
for tag in sorted(tags):
if tag.startswith(tag_prefix):
group_tag_value = tag[len(tag_prefix):]
break

if group_tag_value is None:
group_tag_value = rule.get("default_value", "")

new_rows.append(row + [group_tag_value])

return new_rows, sources


class AddColumnConcatenateRuleDefinition(BaseRuleDefinition):
rule_type = "add_column_concatenate"

Expand Down Expand Up @@ -536,6 +564,7 @@ def display(self):

RULES_DEFINITION_CLASSES = [
AddColumnMetadataRuleDefinition,
AddColumnGroupTagValueRuleDefinition,
AddColumnConcatenateRuleDefinition,
AddColumnBasenameRuleDefinition,
AddColumnRegexRuleDefinition,
Expand Down
3 changes: 3 additions & 0 deletions test/api/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ def test_apply_rules_2(self):
def test_apply_rules_3(self):
self._apply_rules_and_check(rules_test_data.EXAMPLE_3)

def test_apply_rules_4(self):
self._apply_rules_and_check(rules_test_data.EXAMPLE_4)

@skip_without_tool("multi_select")
def test_multi_select_as_list(self):
with self.dataset_populator.test_history() as history_id:
Expand Down
32 changes: 32 additions & 0 deletions test/base/data/rules_dsl_spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,38 @@
final:
data: [["moo", "farm"], ["meow", "house"], ["bark", "firestation,house"]]

- rules:
- type: add_column_group_tag_value
value: where
default_value: ''
initial:
data: [["moo"], ["meow"], ["bark"]]
sources: [{"identifiers": ["cow"], "tags": ["group:where:farm"]}, {"identifiers": ["cat"], "tags": ["group:where:house"]}, {"identifiers": ["dog"], "tags": ["group:where:house"]}]
final:
data: [["moo", "farm"], ["meow", "house"], ["bark", "house"]]

- doc: Test add_column_group_tag_value default value.
rules:
- type: add_column_group_tag_value
value: where
default_value: 'barn'
initial:
data: [["moo"], ["meow"], ["bark"]]
sources: [{"identifiers": ["cow"], "tags": []}, {"identifiers": ["cat"], "tags": ["group:where:house"]}, {"identifiers": ["dog"], "tags": ["group:where:firestation"]}]
final:
data: [["moo", "barn"], ["meow", "house"], ["bark", "firestation"]]

- doc: Test add_column_group_tag_value sorts and grabs first tag value if multiple present.
rules:
- type: add_column_group_tag_value
value: where
default_value: 'barn'
initial:
data: [["moo"], ["meow"], ["bark"]]
sources: [{"identifiers": ["cow"], "tags": []}, {"identifiers": ["cat"], "tags": ["group:where:house", "group:where:kittenpile"]}, {"identifiers": ["dog"], "tags": ["group:where:house", "group:where:firestation"]}]
final:
data: [["moo", "barn"], ["meow", "house"], ["bark", "firestation"]]

- rules:
- type: invalid_rule_type
error: true
Expand Down
11 changes: 9 additions & 2 deletions test/base/populators.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,13 +917,20 @@ def read_test_data(test_dict):
elements_data = value.get("elements", [])
elements = []
for element_data in elements_data:
identifier = element_data["identifier"]
# Adapt differences between test_data dict and fetch API description.
if "name" not in element_data:
identifier = element_data["identifier"]
element_data["name"] = identifier
input_type = element_data.get("type", "raw")
content = None
if input_type == "File":
content = read_test_data(element_data)
else:
content = element_data["content"]
elements.append((identifier, content))
if content is not None:
element_data["src"] = "pasted"
element_data["paste_content"] = content
elements.append(element_data)
# TODO: make this collection_type
collection_type = value["type"]
new_collection_kwds = {}
Expand Down
60 changes: 60 additions & 0 deletions test/base/rules_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ def check_example_3(hdca, dataset_populator):
assert first_element["element_identifier"] == "test0forward"


def check_example_4(hdca, dataset_populator):
assert hdca["collection_type"] == "list:list"
assert hdca["element_count"] == 2
first_collection_level = hdca["elements"][0]
assert first_collection_level["element_identifier"] == "single", hdca
assert first_collection_level["element_type"] == "dataset_collection"
second_collection_level = first_collection_level["object"]
assert "elements" in second_collection_level, hdca
assert len(second_collection_level["elements"]) == 1, hdca
i1_element = second_collection_level["elements"][0]
assert "object" in i1_element, hdca
assert "element_identifier" in i1_element
assert i1_element["element_identifier"] == "i1", hdca


EXAMPLE_1 = {
"rules": {
"rules": [
Expand Down Expand Up @@ -130,3 +145,48 @@ def check_example_3(hdca, dataset_populator):
"check": check_example_3,
"output_hid": 7,
}

# Nesting with group tags.
EXAMPLE_4 = {
"rules": {
"rules": [
{
"type": "add_column_metadata",
"value": "identifier0",
},
{
"type": "add_column_group_tag_value",
"value": "type",
"default_value": "unused"
}
],
"mapping": [
{
"type": "list_identifiers",
"columns": [1, 0],
}
],
},
"test_data": {
"type": "list",
"elements": [
{
"identifier": "i1",
"content": "0",
"tags": ["random", "group:type:single"]
},
{
"identifier": "i2",
"content": "1",
"tags": ["random", "group:type:paired"]
},
{
"identifier": "i3",
"content": "2",
"tags": ["random", "group:type:paired"]
},
]
},
"check": check_example_4,
"output_hid": 8,
}
2 changes: 2 additions & 0 deletions test/galaxy_selenium/navigates_galaxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,8 @@ def tool_open(self, tool_id, outer=False):
tool_link = self.components.tool_panel.outer_tool_link(tool_id=tool_id)
else:
tool_link = self.components.tool_panel.tool_link(tool_id=tool_id)
tool_element = tool_link.wait_for_present()
self.driver.execute_script("arguments[0].scrollIntoView(true);", tool_element)
tool_link.wait_for_and_click()

def tool_parameter_div(self, expanded_parameter_id):
Expand Down
3 changes: 3 additions & 0 deletions test/galaxy_selenium/smart_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ def wait_for_absent_or_hidden(self, **kwds):
def wait_for_absent(self, **kwds):
self._has_driver.wait_for_absent(self._target, **kwds)

def wait_for_present(self, **kwds):
return self._has_driver.wait_for_present(self._target, **kwds)

def assert_absent(self, **kwds):
self._has_driver.assert_absent(self._target, **kwds)

Expand Down
5 changes: 5 additions & 0 deletions test/selenium_tests/test_tool_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ def test_run_apply_rules_3(self):
self._apply_rules_and_check(rules_test_data.EXAMPLE_3)
self.screenshot("tool_apply_rules_example_3_final")

@selenium_test
def test_run_apply_rules_4(self):
self._apply_rules_and_check(rules_test_data.EXAMPLE_4)
self.screenshot("tool_apply_rules_example_4_final")

@selenium_test
@managed_history
def test_run_apply_rules_tutorial(self):
Expand Down

0 comments on commit 5807230

Please sign in to comment.