вторник, 25 октября 2016 г.

Формат даты-времени в параметрах функции, в mvc-контроллере spring

При получении параметра из query-строки в http-запросе, можно задать шаблон для даты-времени (по умолчанию это ISO).
Задаётся аннотацией org.springframework.format.annotation.DateTimeFormat с указанием шаблона.

Пример


@RequestMapping(path = "/test", method = RequestMethod.GET)
public List<MyObject> getTest(
  @RequestParam(name="in_baseDateTime") @DateTimeFormat(pattern="dd.MM.yyyy HH:mm:ss") LocalDateTime baseDateTime){...}

вторник, 18 октября 2016 г.

Тест junit с hamcrest с проверкой коллекции на содержание чего-либо

Часто, я первой проверкой на коллекции в unit-тесте, ставлю простое определение есть ли что-то там или нет.

Обычно (по ленивой привычке) я делал это примерно так:


@Test
public void testNotEmptyList(){
    List<String> list = Arrays.asList("item_1","item_2");
    Assert.assertNotNull(list);
    Assert.assertTrue(list.size() > 0);
}

Но тут решил попробовать Hamcrest matchers и почему-то не сразу понял как там сделать такого рода проверку с коллекциями. Без коллекций всё достаточно понятно, а вот именно с коллекциями как-то не сразу въехал. Но в результате получилось вот так:

...
import org.hamcrest.collection.IsEmptyCollection;
import static org.hamcrest.CoreMatchers.*;
...
@Test
public void testNotEmptyList(){
    List<String> list = Arrays.asList("item_1","item_2");
    Assert.assertThat(list, notNullValue());
    Assert.assertThat(list, not(IsEmptyCollection.emptyCollectionOf(String.class)));
}

Версия Hamcrest должна быть не меньше 1.3

пятница, 30 сентября 2016 г.

Сертификация OCA Java SE 8 Programmer (1Z0-808). Complete

Сегодня сдал Oracle Certified Associate, Java SE 8 Programmer I (1Z0-808) 
(Результат 90%)
С одной стороны хорошо, а с другой - это только часть экзамена :)
В любом случае, полезно.  Но в нём только базовые знания, более глубоко в части II. Посмотрим, может и до неё доберусь.

Готовился со средней интенсивностью около 3-х месяцев. Пользовался следующими вещами:
Книга: 
Тесты:
  - всё, что бесплатно нашёл в интернете
  - книжка "OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam 1Z0-808" ( в ней, кстати, указано где тесты можно взять)
  - набор тестов http://enthuware.com/ (10$)

Этого, на мой взгляд вполне достаточно для успешной сдачи.


четверг, 25 августа 2016 г.

Смешная и грустная цитата из Кобьелла

Просто цитата:

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

Клаусс Кобьел (это тот, что написал "Мотивация в стиле экшн")

понедельник, 18 июля 2016 г.

Русские буквы в имени файла, отдаваемого сервлетом

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

Решение
Имя файла должно быть закодировано  javax.mail.internet.MimeUtility.encodeText()

Т.е. пример должен выглядеть как-то так:

response.setHeader("Content-Type", "application/file; charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="+ MimeUtility.encodeText(dataFilePath.getFileName().toString()));

response.getOutputStream().write(FileUtils.readFileToByteArray(dataFilePath.toFile()));



понедельник, 30 мая 2016 г.

Напоминалка: ссылка на статическое поле в jаvadoc

Чтобы каждый раз заново не вспоминать, как ссылаться на статическое поле(константу) в javadoc-е:

/**
*  Ссылка на описание внешней константы {@link ru.pevgen.test.Consts#MY_CONST} в документации
**/

четверг, 5 мая 2016 г.

GreenMail - простая библиотека для unit-тестирования получения/приёма email в java (spring)

Собственно по теме, чтобы не забыть :  http://www.icegreen.com/greenmail/

Представляет из себя простой почтовый сервер (с разными протоколами  - pop,smtp,imap), который может быть внедрён в код и использован для простого тестирования кода, связанного с посылкой/приёмом email-ов.

Пример конфигурации и работы в тестовой spring-конфигурации

Фактически тут просто в тестовой конфигурации подменяется mail-сервер, на greenmail. А у самого greenmail-объекта есть методы для проверки того, что на него посылалось.
 
https://stackoverflow.com/questions/9661907/testing-greenmail-without-installing-a-smtp-server/9663399#9663399


import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.GreenMailUtil;
import com.icegreen.greenmail.util.ServerSetupTest; ...

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("ApplicationContext-Greenmail.xml")
public class EmailServiceIntegrationTest {

    /** Class under test */
    @Resource
    private EmailService emailService;

    private GreenMail greenMail;

    @Before
    public void startMailServer() {
        greenMail = new GreenMail(ServerSetupTest.SMTP);
        greenMail.start();
    }

    @After
    public void stopMailServer() {
        greenMail.stop();
    }

    @Test
    public void testPledgeReminder()
                throws InterruptedException, MessagingException {

        String mailText = "Hallo World";
        String mailSubject = "Hallo";
        String mailTo = "test@excaple.com";

        /** when: sending a mail */
        emailService.send(mailSubject, mailTo, mailText);

        assertTrue(greenMail.waitForIncomingEmail(5000, 1));
        Message[] messages = greenMail.getReceivedMessages();
        assertEquals(1, messages.length);
        assertEquals(mailText, messages[0].getSubject());       
        String body = GreenMailUtil.getBody(messages[0]).replaceAll("=\r?\n", "");
        assertEquals(mailText, body);       
    }

}
important: use port 3025
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="javaMailProperties">
        <util:properties>
            <prop key="mail.debug">false</prop>
            <prop key="mail.transport.protocol">smtp</prop>
            <prop key="mail.smtp.port">3025</prop>
            <prop key="mail.smtp.auth">true</prop>
            <prop key="mail.smtp.user">test@mail.extern</prop>
            <prop key="mail.smtp.host">localhost</prop>
            <prop key="mail.smtp.from">test@mail.extern</prop>
        </util:properties>
    </property>
    <property name="username" value="test"/>
    <property name="password" value="xxx"/>
    <property name="defaultEncoding" value="utf8" />
</bean>
Then this configuration will configure a Spring JavaMailSender to send its mails to the GreenMail-Server started and finished by the test code.

четверг, 21 апреля 2016 г.

Создание среды для Unit-тестирования JavaScript с помощью Jasmine и Karma (в IntelliJ IDEA). Пошаговое руководство.


Технические средства


  • Node.js (https://nodejs.org) - программная платформа, основанная на движке браузера Chrome V8; позволяет выполнять JavaScript код
  • Karma (https://karma-runner.github.io) - настраиваемый движок, который позволяет запускать тесты (TestRunner)
  • Jasmine(http://jasmine.github.io/) - js-библиотека для unit-тестирования JavaScript
  • PhantomJS(http://phantomjs.org/)  - полноценный браузер на основе WebKit из консоли
  • IntelliJ IDEA(https://www.jetbrains.com/idea/) - IDE-среда для разработки (к сожалению, до сих пор в компании используется уже сильно устаревшая версия 13)
  • Плагины IntelliJ IDEA для Node.js и Karma - дополнительные модули(plugins) для возможности запуска тестов Karma-Jasmine в IDE

Установка в системе


1. Скачать установочный файл Node.js и установить всё по умолчанию (https://nodejs.org/en/ (Версия 5.x) )

2.  Проверить в Windows PowerShell (Все программы/Стандартные/Windows PowerShell/Windows PowerShell)

Команда: node -v

3. Установить библиотеки karma,jasmine,phantomjs в nodejs npm, для чего выполнить команды из под WindowsShell

    npm install -g karma
    npm install -g jasmine
    npm install -g jasmine-core
    npm install -g karma-cli
    npm install -g karma-jasmine
    npm install -g phantomjs-prebuilt
    npm install -g karma-phantomjs-launcher

Установка в IntellijIDEA(13)

В среде

1.Установить плагин Node.js

2. Установить плагин Karma

В проекте

1. Создать в проекте файл конфигурации запуска тестов для Karma, karma.conf.js  

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

Пример karma.config.js
module.exports = function(config) {
    config.set({
        basePath: '',
       // файлы, в которых находится исходный код, необходимые библиотеки, сами тесты
        files: [
            "./base/js/ext-4.2/ext-all.js",
            "./base/js/FormStik.js",
            "./base/js/isuprTrains.js",
            "./test/js/isuprTrains.Test.js"
        ],
        // указать конкретную библиотеку для тестирования
        frameworks: ['jasmine'],
        // если тестировать в phantomjs, т.е. без явного запуска браузера
        browsers: ["PhantomJS"]
    });
};

2. Создать тестовый класс с использованием jasmine, c именем <имя js файла>.Test.js (имя на самом деле не принципиально - оно настраивается в конфиге karma.config.js)

Пример jasmine- unit-теста
describe("First Test", function() {
    it("makes testing JavaScript awesome!", function() {
        expect(true).toBe(true);
    });
});

3. Создать запускающую конфигурацию в проекте


4.Выполнить конфигурацию (Run)

Результат выглядит приблизительно так:


среда, 13 апреля 2016 г.

Про то, как надо делать API

Попалась отличная статья(перевод) на хабре, о том, как надо делать REST API: Разработка web API (перевод)
Жаль, что я не прочитал её на несколько месяцев раньше, когда я переделывал некоторую функциональность на одном из проектов. Хотя приятно, что до некоторых идей получилось додуматься самостоятельно :)

Из интро выяснилось откуда ноги растут: "Это краткий перевод основных тезисов из брошюры «Web API Design. Crafting Interfaces that Developers Love» Брайана Маллоя из компании Apigee Labs"

В общем, читать и перечитывать, пока в голове не застрянет накрепко :)

четверг, 11 февраля 2016 г.

Мои последние достижения на coursera (Build Complete Web Solutions.The Hong Kong University of Science and Technology)

Решил поучиться новым технологиям в области frontend-a. А то что всё сервер да сервер. Хочется иногда чего-то "творческого" :)
На coursera пару месяцев назад началась специализация  Build Complete Web Solutions Гонконгского университета (якобы, номер 1 в Азии). Пока решил всю специализацию не проходить - да и не очень понятно зачем мне это - зато поучиться на отдельных курсах. К моменту начала coursera ещё не стала сильно жадной, и на ряде курсов можно было получить оценку, не покупая сертификат (последний курс прошёл уже без оценок).
В двух словах - интересно и познавательно. Буду пробовать дальше саморазвиваться в эту сторону.
А результат самих курсов, на данный момент, на картинке :


вторник, 9 февраля 2016 г.

Google Sheets. Копирование данных листа google sheet из одного документа в другой.

Дано

1. Документ-источник (google sheet), в котором ведутся некоторые данные.
2. Документ-приёмник (google sheet), в котром на одном из листов надо использовать данные из документа-источника.

Описание решения

В документе-приёмнике в скриптах, пишется код, который запускается регулярно триггером (в моём случае каждый час), и копирует полностью (т.е. накрывает/перезаписывает диапазон ячеек целиком) данные. А также и цветовые схемы (font,background colors) и примечания ячеек, входящих в диапазон.

Код скрипта

function readFomVolonteersQuestionnaire() {
  var RANGE_NAME = "A1:AT202";
  var DEST_SHEET_NAME = "Диапазон";
  
  // Документ - источник
  var spreadsheet = SpreadsheetApp.openById('13d...'); 
  
  var sheet = spreadsheet.getSheets()[0];     // лист с данными (первый в источнике)
  
  var range = sheet.getRange(RANGE_NAME);
  var values = range.getValues();
  var backgroundColors = range.getBackgrounds();// цвет фона
  var fontColors = range.getFontColors();// цвет текста
  var notes = range.getNotes();  // примечания

  
  // Текущий документ (приёмник данных)
  var ss = SpreadsheetApp.getActiveSpreadsheet();  // активный документ (из которого запускается скрипт)
  var SSsheet = ss.getSheetByName(DEST_SHEET_NAME);
  var ssRange = SSsheet.getRange(RANGE_NAME);
  ssRange.setValues(values);
  ssRange.setBackgrounds(backgroundColors);
  ssRange.setFontColors(fontColors);
  ssRange.setNotes(notes);  // примечания 
}