Ссылки о веб-разработке за июнь 2014

глобальная имитация

в angular.js есть удобный механизм инъекции зависимостей. Среди прочего он позволяет довольно удобным образом подменять эти зависимости имитациями при модульном тестировании: достаточно написать $provide.value('name', mockedDependency). Ну и создать эту имитацию тоже нужно.

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

я вдохновился тем, как разработчики самого angular.js создали отдельный файл с имитациями популярных модулей — angular-mocks.js. (Достаточно подключить его в страницу тестов, и работать с таймаутами, HTTP и обещаниями станет намного проще.) Нам было нужно что-то вроде этого, но для всех наших модулей. Для директив и контроллеров всё очевидно, но вот тестировать модули, для которых заглушки уже есть, так не получится: тесты будут ожидать реальных результатов от имитации. Поэтому нашу глобальную имитацию использовать слегка сложнее: помимо подключения файла нужно ещё указать, что именно будет имитироваться. Например, в начале теста директивы, для которой нет заглушки, мы пишем beforeEach(NS.mocks.all()). А вот в начале теста модуля routing, для которого есть заглушка, ставится beforeEach(NS.mocks.except('routing')).

NS.mocks.all = function() {
    return function() {
        module(function($provide) {
            Object.keys(NS.mocks.factories).forEach(function(mockName) {
                var mockInstance = NS.mocks.factories[mockName]();
                $provide.value(mockName, mockInstance);
            });
        });
    };
};

NS.mocks.except = function(excludedName) {
    if (!(excludedName in NS.mocks.factories)){
        throw new Error("Don't forget to implement mock for " + excludedName + " in mocks.js");
    }

    return function() {
        module(function($provide) {
            var mocks = Object.keys(NS.mocks.factories).filter(function(name) {
                return (name !== excludedName);
            });
            mocks.forEach(function(mockName) {
                var mockInstance = NS.mocks.factories[mockName]();
                $provide.value(mockName, mockInstance);
            });
        });
    };
};

NS.mocks.factories.routing = function() {
    return jasmine.createSpyObj('routing', ['to', 'from']);
};

Обновился HTTP/1.1

Вот так неожиданно, через 15 лет после начальной публикации, обновилась спецификация HTTP/1.1
Обновлений много, я бы даже сказал, дофига. Добавили много проясняющего текста, разбили спецификацию на 6 RFC (раньше было 2), добавили новый статус 308, стандартизировали X-Forwarded-For (теперь он просто Forward), и еще много всего.

Неполный спискок изменений:


Новые RFC:

влияние дизайна DNS на безопасность

элементы доменного имени расположены в порядке «от специфичного к общему». Элементы пути в URL расположены в порядке «от общего к специфичному», так же, как и в файловой системе, и во многих других. Конечно, уже давно поздно это менять, но мне кажется, что было бы удобнее иметь в этих двух частях URL одинаковый порядок. И лучше ему быть именно «от общего к специфичному»: ru.gov.kremlin.documents/laws/12345.html. Если бы мы использовали его с самого начала, у нас бы не было проблемы безопасности «поддомен evil.com притворяется, что он на самом деле paypal.com»

← предыдущий месяц