0

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

return { 
    restrict: 'A', 
    scope: { 
     imageLoad: '@' 
    }, 
    link: function(scope, element, attrs) { 

     attrs.$observe('imageLoad', function (url) { 
      var deferred = $q.defer(), 
       image = new Image(); 

      image.onerror = function() { 
       deferred.resolve(false); 
      }; 

      image.onload = function() { 
       deferred.resolve(true); 
      }; 

      image.src = url; 
      return deferred.promise; 
     }); 

    } 
}; 

Все я затем нужно сделать, это два простых тестов, которые проверяют image.onerror и image.onload, но я, кажется, только попасть в на функцию ошибок, вот что я до сих пор:

compileDirective = function() { 
    var element = angular.element('<div data-image-load="http://placehold.it/350x150"></div>'); 
    $compile(element)(scope); 
    $rootScope.$digest(); 
    return element; 
}; 

beforeEach(inject(function (_$compile_, _$rootScope_) { 
    $compile = _$compile_; 
    $rootScope = _$rootScope_; 
    scope = $rootScope.$new(); 
})); 

it('should do something', function() { 
    var compiledElement, isolatedScope; 
    compiledElement = compileDirective(); 
    isolatedScope = compiledElement.isolateScope(); 
    expect(true).toBe(true); 
}); 

, очевидно, этот тест проходит, как он просто ожидает, что верно будет правда, однако с точки зрения охвата это попадает в t он работает onerror, поэтому мне почему-то нужно проверить, что отложенный.прогноз должен возвращать false.

так в конечном счете две части вопроса, как я получаю результат deferred.resolve?

и, во-вторых, как мне попасть в функцию onload?

я имел взгляд вокруг и видел некоторые предложения, добавив следующее:

element[0].setAttribute('imageLoad','http://placehold.it/350x150'); 
$compile(element)(scope); 
element.trigger('imageLoad'); 

и оставляя data-image-load="" пустым, но не казалось, везения, любые предложения было бы здорово.

+0

Это не связано с вашим вопросом, а есть ли особая причина, вы используете 'AttrS $ observe'.? Прямо сейчас вы можете просто удалить это и заменить 'url'' scope.imageLoad'. Прямо сейчас анонимная функция, переданная в '$ observ', просто возвращает обещание, но никто не сможет посмотреть на результат. В чем смысл этой директивы? Как он должен использоваться? – tasseKATT

+0

@tasseKATT в основном путь изображения в реальном приложении будет динамичным и в результате может измениться, поэтому его необходимо повторно запустить. обещание гарантирует, что он загружен, если он не сработает, я бы служил резервным изображением, я пропустил какой-то код из приведенного выше примера, где я установил резервное изображение, используя element.css (background image) – gardni

+0

Так что сама директива единственный реагирует на результат обещания? – tasseKATT

ответ

1

Из того, что вы показали, вам не нужно обещать вообще.

Даже если вы сделали, так как обещание используется только внутренне, и никто не использует результат, его следует рассматривать в деталях реализации и ваш тест не должен заботиться об этом.

Допустим, вы имеете следующую директиву:

app.directive('imageLoad', function() { 
    return { 
    restrict: 'A', 
    scope: { 
     imageLoad: '@' 
    }, 
    link: function(scope, element, attrs) { 

     var fallback = 'http://placekitten.com/g/200/300'; 

     attrs.$observe('imageLoad', function(url) { 

     var image = new Image(); 

     image.onerror = function(e) { 

      setBackground(fallback); 
     }; 

     image.onload = function() { 

      setBackground(url); 
     }; 

     image.src = url; 
     }); 

     function setBackground(url) { 
     element.css({ 
      'background': 'url(' + url + ') repeat 0 0' 
     }); 
     } 
    } 
    }; 
}); 

Демонстрация этого в использовании:http://plnkr.co/edit/3B8t0ivDbqOWU2YxgrlB?p=preview

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

Так что вы хотите, чтобы проверить это:

  1. Переданный URL работает - следует использовать принятый URL в качестве фона.
  2. Пропущенный URL не работает - следует использовать запасной фон в качестве фона.

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

Чтобы предотвратить какой-либо сетевой трафик в вашем тесте, я бы рекомендовал использовать URI данных вместо URL-адресов.

Пример:

var validImage = 'data:image/jpeg;base64, + (Valid data omitted)'; 
var invalidImage = 'data:image/jpeg;base64,'; 

Полный пример:

describe('myApp', function() { 

    var $compile, 
    $rootScope; 

    beforeEach(module('myApp')); 

    beforeEach(inject(function(_$compile_, _$rootScope_) { 
    $compile = _$compile_; 
    $rootScope = _$rootScope_; 
    })); 

    var validImage = 'data:image/jpeg;base64, + (Valid data omitted)'; 
    var invalidImage = 'data:image/jpeg;base64,'; 

    compileDirective = function(url) { 
    var element = angular.element('<div data-image-load="' + url + '"></div>'); 
    return $compile(element)($rootScope.$new()); 
    }; 

    it('should use correct background when image exists', function(done) { 

    var element = compileDirective(validImage); 

    $rootScope.$digest(); 

    setTimeout(function() { 

     var background = element.css('background'); 
     expect(background).toBe('url("' + validImage + '") 0px 0px repeat'); 

     done(); 

    }, 100); 
    }); 

    it('should use fallback background when image does not exist', function(done) { 

    var element = compileDirective(invalidImage); 

    $rootScope.$digest(); 

    setTimeout(function() { 

     var background = element.css('background'); 
     expect(background).toBe('url("http://placekitten.com/g/200/300") 0px 0px repeat'); 

     done(); 

    }, 100); 
    }); 
}); 

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

Подробнее о том, как это делается с Жасмин here.

Демо:http://plnkr.co/edit/W2bvHih2PbkHFhhDNjrG?p=preview

+1

благодарим вас за такой отличный ответ, явно потратив много времени на понимание проблемы и разработку решения, я был обеспокоен тем, что мой подход изначально мог быть неправильным, это решение работало отлично, мне особенно понравилось ваше предложение для кодировки base64. – gardni

+0

@ gardni Добро пожаловать :) – tasseKATT

 Смежные вопросы

  • Нет связанных вопросов^_^