iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0

Current Sprint: 1. 完成 HappyPath: 可以建立一場遊戲,玩到結束
repo: https://github.com/side-project-at-SPT/ithome-ironman-2024-san-juan
swagger docs: https://side-project-at-spt.github.io/ithome-ironman-2024-san-juan/

前情提要

經過一週之後,決定先放棄套方法論了 XDD

先按照直覺開發,後面再來看看有沒有辦法讓文章結構變得順暢

Sprint 1 需求

  1. 「使用者」可以建立一場遊戲 -> 遊戲建立成功,「使用者」成為了「玩家」
  2. 「玩家」可以選擇職業:礦工 -> 執行行動成功
  3. 「使用者」可以查看遊戲狀態

「使用者」可以查看遊戲狀態

  1. 建立遊戲的 controller
rails g games
      # create  app/controllers/games_controller.rb
      # invoke  rspec
      # create    spec/requests/games_spec.rb
  1. 編輯 games_spec.rb
require 'swagger_helper'

RSpec.describe "Api::V1::Games", type: :request do
  path '/api/v1/games' do
    get 'List all games' do
      tags 'Games'
      produces 'application/json'

      response '200', 'Games found' do
        schema type: :object,
          properties: {
            games: {
              type: :array,
              items: {
                type: :object,
                properties: {
                  id: { type: :integer },
                  status: { type: :string }
                },
                required: [ 'id', 'status' ]
              }
            }
          },
          required: [ 'games' ]

        run_test!
      end
    end
  end
end
  1. 增加 game route
# config/routes.rb
# 加上 game route

Rails.application.routes.draw do
  # ...

  namespace :api do
    namespace :v1 do
      resources :games, only: [ :index ]
    end
  end
end
  1. 加上 index action (所有 games)
# app/controllers/api/v1/games_controller.rb

class Api::V1::GamesController < ApplicationController
  def index
    render json: { games: [ a: 1 ] }
  end
end
  1. 跑測試看看
rspec spec/requests/api/v1/games_spec.rb

# F

# Failures:

#   1) Api::V1::Games /api/v1/games get Games found returns a 200 response
#      Failure/Error:
#        raise UnexpectedResponse,
#              "Expected response body to match schema: #{errors.join("\n")}\n" \
#              "Response body: #{JSON.pretty_generate(JSON.parse(body))}"

#      Rswag::Specs::UnexpectedResponse:
#        Expected response body to match schema: The property '#/games/0' did not contain a required property of 'id' in schema 5c48736f-3746-5bb8-9970-fdb5b154e5fe
#        The property '#/games/0' did not contain a required property of 'status' in schema 5c48736f-3746-5bb8-9970-fdb5b154e5fe
#        Response body: {
#          "games": [
#            {
#              "a": 1
#            }
#          ]
#        }
  1. 建立 game model
# 建立 game model, 欄位 status type = integer, 並且如果沒宣告 id, 則會自動帶入 id = auto increment integer
rails g model game status:integer
      # invoke  active_record
      # create    db/migrate/20240908153434_create_games.rb
      # create    app/models/game.rb
      # invoke    rspec
      # create      spec/models/game_spec.rb
  1. 編輯 migration
# 增加 null: false, default: 0 # 0: unknown, 1: playing, 2: finished

class CreateGames < ActiveRecord::Migration[7.2]
  def change
    create_table :games do |t|
      t.integer :status, null: false, default: 0 # 0: unknown, 1: playing, 2: finished

      t.timestamps
    end
  end
end
  1. 執行 db migrate
rails db:migrate
# == 20240908153434 CreateGames: migrating ======================================
# -- create_table(:games)
#    -> 0.0117s
# == 20240908153434 CreateGames: migrated (0.0118s) =============================
  1. 修改 Game, 加上 enum 宣告
# app/models/game.rb

class Game < ApplicationRecord
  enum :status, {
    unknown: 0,
    playing: 1,
    finished: 2
  }, prefix: true
end
  1. 修改 spec, 增加 before action
require 'swagger_helper'

RSpec.describe "Api::V1::Games", type: :request do
  path '/api/v1/games' do
    get 'List all games' do
      tags 'Games'
      produces 'application/json'

      before do
        Game.create
        Game.create(status: 'playing')
      end

      response '200', 'Games found' do
        schema type: :object,
          properties: {
            games: {
              type: :array,
              items: {
                type: :object,
                properties: {
                  id: { type: :integer },
                  status: { type: :string }
                },
                required: [ 'id', 'status' ]
              }
            }
          },
          required: [ 'games' ]

        run_test! do
          json = JSON.parse(response.body)
          expect(json['games'].size).to eq(2)
          expect(json['games'].any? { |game| game['status'] == 'unknown' }).to be_truthy
          expect(json['games'].any? { |game| game['status'] == 'playing' }).to be_truthy
        end
      end
    end
  end
end
  1. 測試看看
rspec spec/requests/api/v1/games_spec.rb
# .

# Finished in 0.08544 seconds (files took 0.67108 seconds to load)
# 1 example, 0 failures
  1. 可以把 before block 拿掉,看看測試結果如何?
rspec spec/requests/api/v1/games_spec.rb

# F

# Failures:

#   1) Api::V1::Games /api/v1/games get Games found returns a 200 response
#      Failure/Error: expect(json['games'].size).to eq(2)

#        expected: 2
#             got: 0

#        (compared using ==)
#      # ./spec/requests/api/v1/games_spec.rb:33:in `block (5 levels) in <top (required)>'

  1. 產生 swagger
rails rswag
  1. run server
rails s
  1. 查看 swagger (go to localhost:3000/api-docs)
    https://ithelp.ithome.com.tw/upload/images/20240908/20150987eWS5jisxI1.png

  2. 執行看看
    https://ithelp.ithome.com.tw/upload/images/20240908/20150987uIC9dNzrds.png

小結

完成了 0.5 XD

明天要做什麼

  1. 「玩家」可以選擇職業:礦工 -> 執行行動成功
  2. 「使用者」可以查看遊戲狀態

以上不代表明天會做,如有雷同純屬巧合


工商服務

SPT (Side Project Taiwan) 的宗旨是藉由Side Project開發來成就自我,透過持續學習和合作,共同推動技術和專業的發展。我們相信每一個參與者,無論是什麼專業,都能在這個社群中找到屬於自己的成長空間。

歡迎所有對Side Project開發有興趣的人加入我們,可以是有點子來找夥伴,也可以是來尋找有興趣的Side Project加入,邀請大家一同打造一個充滿活力且有意義的技術社群!

Discord頻道連結:https://sideproj.tw/dc


上一篇
Day 06 - modeling
下一篇
Day 08 - 完成 Sprint 1 - 可以建立一場遊戲,玩到結束啦
系列文
透過實作網頁遊戲練習網站工程師的基本素養,以 San Juan(聖胡安) 為例。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
vincentxu
iT邦新手 4 級 ‧ 2024-09-09 00:00:25

認真的鵝就是推/images/emoticon/emoticon74.gif

我要留言

立即登入留言