From 19682f8baa4174b11a4f023b336ea82c4133d4d8 Mon Sep 17 00:00:00 2001 From: Neil Bedi Date: Fri, 29 Jul 2016 23:39:41 -0700 Subject: [PATCH] Slug now accepts multiple column names to merge. Closes #617 --- agate/computations/slug.py | 34 +++++++++++++++++++++++++--------- tests/test_computations.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/agate/computations/slug.py b/agate/computations/slug.py index a1a333547..b6780e68c 100644 --- a/agate/computations/slug.py +++ b/agate/computations/slug.py @@ -4,15 +4,18 @@ from agate.computations.base import Computation from agate.data_types import Text from agate.exceptions import DataTypeError -from agate.utils import slugify +from agate.utils import slugify, issequence class Slug(Computation): """ - Convert text values into a column into slugs. + Convert text values from one or more columns into slugs. If multiple column + names are given, values from those columns will be appended in the given + order before standardizing. :param column_name: - The name of a column containing the :class:`.Text` values. + The name of a column or a sequence of column names containing + :class:`.Text` values. :param ensure_unique: If True, any duplicate values will be appended with unique identifers. Defaults to False. @@ -26,13 +29,19 @@ def get_computed_data_type(self, table): return Text() def validate(self, table): - column = table.columns[self._column_name] + if issequence(self._column_name): + column_names = self._column_name + else: + column_names = [self._column_name] - if not isinstance(column.data_type, Text): - raise DataTypeError('Slug column must contain Text data.') + for column_name in column_names: + column = table.columns[column_name] - if HasNulls(self._column_name).run(table): - raise ValueError('Slug column cannot contain `None`.') + if not isinstance(column.data_type, Text): + raise DataTypeError('Slug column must contain Text data.') + + if HasNulls(column_name).run(table): + raise ValueError('Slug column cannot contain `None`.') def run(self, table): """ @@ -42,6 +51,13 @@ def run(self, table): new_column = [] for row in table.rows: - new_column.append(row[self._column_name]) + if issequence(self._column_name): + column_value = '' + for column_name in self._column_name: + column_value = column_value + ' ' + row[column_name] + + new_column.append(column_value) + else: + new_column.append(row[self._column_name]) return slugify(new_column, ensure_unique=self._ensure_unique, **self._slug_args) diff --git a/tests/test_computations.py b/tests/test_computations.py index 79526328d..78cb2b06f 100644 --- a/tests/test_computations.py +++ b/tests/test_computations.py @@ -365,6 +365,36 @@ def test_slug(self): ) expected = ['hello-world', 'ab-c-e', 'he11o-w0rld'] + table = Table(rows, ['one', 'two'], [self.text_type, self.number_type]).compute([ + ('slugs', Slug('one')) + ]) + + self.assertSequenceEqual(table.columns['slugs'], expected) + + def test_slug_column_name_sequence(self): + rows = ( + ('hello world', 2, 'Ab*c #e'), + ('Ab*c #e', 2, 'He11O W0rld'), + ('He11O W0rld', 3, 'hello world') + ) + expected = ['hello-world-ab-c-e', 'ab-c-e-he11o-w0rld', 'he11o-w0rld-hello-world'] + + table1 = Table(rows, ['one', 'two', 'three'], [self.text_type, self.number_type, self.text_type]) + table2 = table1.compute([ + ('slugs', Slug(['one', 'three'])) + ]) + + self.assertSequenceEqual(table2.columns['slugs'], expected) + + def test_slug_ensure_unique(self): + rows = ( + ('hello world', 2), + ('Ab*c #e', 2), + ('He11O W0rld', 3), + ('HellO WOrld ', 3) + ) + expected = ['hello-world', 'ab-c-e', 'he11o-w0rld', 'hello-world-1'] + table = Table(rows, ['one', 'two'], [self.text_type, self.number_type]).compute([ ('slugs', Slug('one', ensure_unique=True)) ])