Тестирование для коллекционных типов индекса (то есть аргументов к методу []) - PullRequest
0 голосов
/ 27 мая 2009

Какой эффективный, рубиновый способ тестирования, если коллекция поддерживает индексирование строк?

Длинная версия: Я хотел бы, чтобы мой класс нормализовал определенные значения. Чтобы достичь этого, экземпляр принимает коллекцию значений в качестве своего атрибута «values». Я бы хотел, чтобы values= принимал как списки (целочисленные индексированные коллекции, включая встроенный массив), так и ассоциативные массивы (объектно-индексированные коллекции, такие как Hash). Если передан список, он превращает список в ассоциативный массив путем инвертирования ключей и значений. Это означает, что метод должен отличать списки от ассоциативных массивов. Он также должен работать с любой индексированной коллекцией, а не только с потомками Array и Hash, поэтому любой тип, перехватывающий тип коллекции, считается уродливым и неправильным. Тип нюхает индексный тип, однако ...

В настоящее время я использую исключения, чтобы определить разницу, но я предпочитаю использовать исключения для исключительных обстоятельств, а не для общей структуры управления. Это просто личное предпочтение, к которому я не слишком привязан. Если исключения являются рубиновым способом решения этой проблемы, пожалуйста, дайте мне знать.

def values=(values)
    begin
        values['']
        @values = values.dup
    rescue TypeError
        @values = Hash[ values.zip((0..values.length-1).to_a) ]
    end
    @values.each_value { |v| @values[v] = v}
end

Примечание: для полного решения потребуется транзитивное замыкание values, но сейчас я могу предположить, что ключи и значения values относятся к разным доменам.

Смысл всего этого в том, чтобы включить код вроде:

toggle.values = [:off, :on]
toggle.normalise(:off) == 0
toggle.normalise(1) == 1

bool.values = {:off => 0, :false => 0, :no => 0,
               :on => 1,  :true => 1,  :yes => 1}
bool.normalise(:yes) == 1
bool.normalise(0) == 0

PS. Это для личного проекта, поэтому элегантность и стиль Ruby имеют первостепенное значение. Я ищу интересные подходы, особенно если они иллюстрируют интересную концепцию (например, «исключения могут использоваться в качестве поведенческих тестов»).

1 Ответ

2 голосов
/ 27 мая 2009

Утка набирает на помощь!

 hash = if collection.respond_to? :to_hash
          collection.to_hash
        elsif collection.respond_to? :to_ary
          collection.to_ary.inject({}) { |_hash,(key,value)| _hash.merge!(key => value) }
        else if collection.respond_to? :inject
          collection.inject({}) { |_hash,(key,value)| _hash.merge!(key => value) }
        else
          raise ArgumentError, "not a collection type I understand"
        end
 if want_dupe and collection.object_id == hash.object_id
    hash = hash.dup
 end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...