В части I мы создали сайт Sinatra для чтения изображений из каталога. Теперь мы собираемся создать форму для загрузки изображений вместе с тестами, чтобы убедиться, что она работает.
Для этого вам понадобится форма с вводом файла. Давайте напишем тест, чтобы убедиться, что это произойдет.
Тест / test.rb
...
def test_for_upload_form
get '/upload'
assert last_response.ok?
assert last_response.body.include?("type=\"file\"")
end
...
Этот тест проверяет, что одним из входных данных формы будет тип «файл». Это еще не так, поэтому тест должен провалиться.
$ ruby test/test.rb
Run options: --seed 34613
# Running tests:
..F
Finished tests in 0.022114s, 135.6607 tests/s, 180.8809 assertions/s.
1) Failure:
test_for_upload_form(MyTest) [test/test.rb:27]:
Failed assertion, no message given.
3 tests, 4 assertions, 1 failures, 0 errors, 0 skips
Моя линия 27
assert last_response.ok?
Если вам интересно, запустите приложение и перейдите на страницу / загрузки .
Похоже, нам нужен обработчик маршрута для загрузки. Добавьте это в файл main.rb.
main.rb
get '/upload' do
"Hello World"
end
Как вы думаете, тест пройдет или не пройдет? Запустите его и узнайте.
$ ruby test/test.rb
Run options: --seed 10631
# Running tests:
F..
Finished tests in 0.022114s, 135.6607 tests/s, 226.1011 assertions/s.
1) Failure:
test_for_upload_form(MyTest) [test/test.rb:28]:
Failed assertion, no message given.
3 tests, 5 assertions, 1 failures, 0 errors, 0 skips
Предыдущая ошибка исчезла, но теперь появилась новая. У нас нет формы для этой страницы.
main.rb
...
get '/upload' do
erb :upload
end
...
@@upload
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=yes, width=device-width" />
<title>Upload Moving Pictures</title>
</head>
<body>
<form action="/upload" enctype="multipart/form-data" method="post">
<label for="file">File to upload:</label>
<input id="file" type="file" name="file">
<input id="submit" type="submit" name="submit" value="Upload picture!">
</form>
</body>
</html>
...
Если вы помните, мы используем удобные встроенные представления Синатры. Теперь, когда у нас есть форма, которая позволит нам загрузить фотографию, вы думаете, тест пройдет на этот раз?
$ ruby test/test.rb
Run options: --seed 6047
# Running tests:
...
Finished tests in 0.022980s, 130.5483 tests/s, 217.5805 assertions/s.
3 tests, 5 assertions, 0 failures, 0 errors, 0 skips
У вас есть страница загрузки и форма, которая имеет возможность выбрать файл. Какой следующий шаг? Да, загрузите файл в каталог public / slideshow_pictures . Давайте напишем тест, который опубликует наш новый обработчик маршрута загрузки и сообщит, что загрузка произошла.
Тест / test.rb
...
def test_upload_file
post '/upload'
assert last_response.ok?
assert last_response.body.include?("Uploaded")
end
...
Запустите тест.
$ ruby test/test.rb
Run options: --seed 59047
# Running tests:
...F
Finished tests in 0.023828s, 167.8697 tests/s, 251.8046 assertions/s.
1) Failure:
test_upload_file(MyTest) [test/test.rb:33]:
Failed assertion, no message given.
4 tests, 6 assertions, 1 failures, 0 errors, 0 skips
Ответ был не в порядке. Просто из любопытства иди и запусти сервер
$ ruby main.rb
Перейти на страницу загрузки. и отправьте форму. Вот что приложение дало мне:
Это предлагает текст в файл main.rb, но давайте изменим «Hello World» на «Uploaded».
main.rb
post "/upload" do
"Uploaded."
end
Запустите тест. Это прошло? Здорово. Поздравляем, мы только что написали ужасный тест. Имя теста — test_upload_file. , но мы даже не проверяли, было ли загружено что-нибудь. Как бы вы проверили это?
Вы можете посчитать количество файлов в каталоге slideshow_picture . Загрузите файл и проверьте, увеличилось ли количество файлов на один. Давайте перепишем тест.
Тест / test.rb
...
def test_upload_file
pictures_before = load_pictures.length
post '/upload'
pictures_after = load_pictures.length
assert_equal (pictures_before + 1), pictures_after
end
...
Давайте попробуем это. Запустите тест.
$ ruby test/test.rb
Run options: --seed 51246
# Running tests:
..F.
Finished tests in 0.030883s, 129.5211 tests/s, 194.2816 assertions/s.
1) Failure:
test_upload_file(MyTest) [test/test.rb:35]:
Expected: 2
Actual: 1
4 tests, 6 assertions, 1 failures, 0 errors, 0 skips
Лучше. Это не должно быть тестом на лету. У нас нет кода для загрузки файла в обработчике маршрута post '/upload'
Давайте добавим это.
main.rb
post "/upload" do
File.open('public/slideshow_pictures/' + params['file'][:filename], "w") do |f|
f.write(params['file'][:tempfile].read)
end
"Uploaded."
end
Здесь мы берем файл из формы, open
Думаешь тест пройдёт сейчас? У нас есть код для записи файла. Запустите его и посмотрите.
$ ruby test/test.rb
Run options: --seed 51246
# Running tests:
..F.
Finished tests in 0.030883s, 129.5211 tests/s, 194.2816 assertions/s.
1) Failure:
test_upload_file(MyTest) [test/test.rb:35]:
Expected: 2
Actual: 1
4 tests, 6 assertions, 1 failures, 0 errors, 0 skips
Что произошло? Мы разместили метод загрузки. Подождите, мы отправили файл? Нам нужно отправить файл param для загрузки метода.
test.rb
...
post '/upload', {:file =>{:filename=>"cat.jpg"}}
...
Это создаст пустой файл с именем cat.jpg Как насчет этого времени … пройдет тест?
$ ruby test/test.rb
Run options: --seed 42496
# Running tests:
....
Finished tests in 0.078357s, 51.0484 tests/s, 76.5726 assertions/s.
4 tests, 6 assertions, 0 failures, 0 errors, 0 skips
Сладкий. Король мира!
Просто для удовольствия, давайте снова проведем тест и посмотрим на удивительность.
$ ruby test/test.rb
Run options: --seed 25680
# Running tests:
F...
Finished tests in 0.083972s, 47.6349 tests/s, 71.4524 assertions/s.
1) Failure:
test_upload_file(MyTest) [test/test.rb:35]:
Expected: 3
Actual: 2
4 tests, 6 assertions, 1 failures, 0 errors, 0 skips
Теперь это как прощание с королями! Что произошло? Если вы посмотрите в каталог public / slideshow_pictures , то уже есть cat.jpg . Мы просто переписываем его, когда загружаем в тест другой файл cat.jpg . Это означает, что мы не увеличиваем количество файлов, поэтому тест не пройден.
Как бы вы удалили этот файл? Один из вариантов — посмотреть, существует ли файл . Если это произойдет, удалите его.
Тест / test.rb
...
def test_upload_file
if File.exists?("public/slideshow_pictures/cat.jpg")
File.delete("public/slideshow_pictures/cat.jpg")
end
pictures_before = load_pictures.length
post '/upload', {:file =>{:filename=>"cat.jpg"}}
pictures_after = load_pictures.length
assert_equal (pictures_before + 1), pictures_after
end
...
Перезапустите тест.
$ ruby test/test.rb
Run options: --seed 12414
# Running tests:
....
Finished tests in 0.069093s, 57.8930 tests/s, 86.8395 assertions/s.
4 tests, 6 assertions, 0 failures, 0 errors, 0 skips
Вы должны получить тот же результат, если снова запустите тест.
Теперь у нас есть сайт, который может загружать изображения и отображать их.
Давайте рассмотрим, что мы сделали.
- Мы написали и теперь можем распознать бесполезный тест.
- Мы научились видеть, существуют ли файлы.
- Мы узнали, как удалять файлы.
В следующей (и последней) статье этой серии мы добавим немного CSS, проверим конкретные типы файлов и завершим наше основное приложение для отображения изображений.