Различные алгоритмы std :: random_shuffle приводят к сбою модульного теста на симуляторе iOS

0

Я пишу приложение для iPad с помощью Xcode 5.0. Я попытался реализовать категорию, которая позволит перетасовать NSMutableArray. Я использую Test Driven Development, и я написал тест, подобный следующему, используя Objective-С++:

size_t randomInteger(size_t);

@implementation ShuffleArrayTests

- (void)testsShufflesAnArray
{
    NSMutableArray* array = [@[@"one", @"two", @"three", @"four", @"five",
        @"six", @"seven", @"eight", @"nine", @"ten"] mutableCopy];

    std::vector<__unsafe_unretained id> values(array.count);
    [array getObjects:&values[0] range:NSMakeRange(0, array.count)];

    ::srandom(0);
    std::random_shuffle(values.begin(), values.end(), randomInteger);

    NSMutableArray* expectedValues =
        [NSMutableArray arrayWithObjects:&values[0] count:values.size()];

    ::srandom(0);
    [array shuffle];

    XCTAssertEqualObjects(expectedValues, array);
}

Реализация метода категорий тасовки записывается следующим образом, также в Objective-С++:

- (void)shuffle
{
    std::vector<__unsafe_unretained id> buffer(self.count);

    [self getObjects:&buffer[0] range:NSMakeRange(0, self.count)];

    std::random_shuffle(buffer.begin(), buffer.end(), randomInteger);

    [self setArray:[NSMutableArray arrayWithObjects:&(buffer[0])
        count:buffer.size()]];
}

и randomInteger в основном реализуется следующим образом:

size_t randomInteger(size_t limit)
{
    return ::random() % limit;
}

Можно было бы подумать, что необходимо установить одно и то же значение семени перед выполнением каждого случайного перетасовки, которое пройдет тест, и ожидаемый массив будет соответствовать фактическому массиву.

Однако тест не работает на iOS-симуляторе, и он несколько раз задумывался о том, почему. Я наконец понял, что тест вызывает другую версию std :: random_shuffle, чем то, что используется в реализации категории. Я не знаю, почему это происходит. Что можно сделать, чтобы код проверки и реализации использовал один и тот же алгоритм std :: random_shuffle?

Теги:
stl

2 ответа

0

Ожидаемые значения не перетасовываются дважды. Содержимое массива копируется и перетасовывается. Результаты скопированного перетасовки хранятся в ожидаемых результатах

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

Кажется, я нашел проблему. Этот проект был первоначально создан с использованием Xcode 4.6, работающего на Mac OS X 10.7. Я обновился до Xcode 5, работающего на OS X 10.9, и похоже, что некоторые параметры, которые должны были быть изменены, не изменились. Я создал новое приложение с нуля и поставил тест в этом приложении, и он прошел отлично. Затем я смог посмотреть на различия между проектом.

Для самого приложения я обнаружил, что в настройках сборки в Apple LLVM 5.0 - Language - C++ стандартная библиотека C++ была установлена в Compiler Default; Я изменил его на lib C++ (стандартная библиотека LLVM C++ с поддержкой C++ 11], и это, похоже, устраняет проблему.

0

Мне кажется, что у вас есть логическая проблема в вашем тесте.

Во-первых, вы создаете array и вставляете в него кучу значений. Все идет нормально.

Во-вторых, вы копируете их в values и перетасовываете их. Все еще прекрасно.

В-третьих, вы копируете элементы из values в expectedValues и перетасовываете их. ОК

Наконец, вы ожидаете, что содержимое array и expectedValues значений expectedValues одинаковым. Почему вы думаете, что это будет так? expectedValues - это в основном array, перетасованный дважды.

Если я понимаю, что вы пытаетесь проверить, я думаю, вы хотите скопировать из array в expectedValues и перетасовать это, а затем сравнить expectedValues values и values.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню