name: Test

on: [push, pull_request]

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        go: ['1.15.x', '1.16.x', '1.17.x', '1.18.x']
    name: Test with Go ${{ matrix.go }} on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    env:
      DISPLAY: ':99.0'
    defaults:
      run:
        shell: bash
    steps:
      - name: Git
        run: |
          # See actions/checkout#135
          git config --global core.autocrlf false
          git config --global core.eol lf

      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Go
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go }}

      - name: Setup JDK
        uses: actions/setup-java@v2
        with:
          java-version: '11'
          distribution: 'adopt'

      - name: Install dependencies
        if: ${{ startsWith(matrix.os, 'ubuntu-') }}
        run: |
          sudo apt-get update
          sudo apt-get install libasound2-dev libgl1-mesa-dev libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev libxxf86vm-dev

      - name: Install wasmbrowsertest
        run: |
          # TODO: Use go install github.com/agnivade/wasmbrowsertest@... on Go 1.16 or later.
          mkdir /tmp/wasmbrowsertest
          cd /tmp/wasmbrowsertest
          go mod init foo
          go get github.com/agnivade/wasmbrowsertest
          go build -o wasmbrowsertest github.com/agnivade/wasmbrowsertest
          mv ./wasmbrowsertest $(go env GOPATH)/bin/go_js_wasm_exec

      - name: Prepare ebitenmobile test
        if: ${{ !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') }}
        run: |
          local_ebiten=$(pwd)
          cd /tmp
          git clone --depth=1 https://github.com/hajimehoshi/go-inovation
          cd go-inovation
          go mod edit -replace=github.com/hajimehoshi/ebiten/v2=$local_ebiten
          go mod tidy

      - name: Xvfb
        if: ${{ startsWith(matrix.os, 'ubuntu-') }}
        run: |
          Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &

      - name: go vet
        if: ${{ !startsWith(matrix.os, 'windows-') }} # TODO: Fix go vet errors on Windows. (#1306)
        run: |
          go vet -tags=example -v ./...

      - name: go vet (atomic align)
        run: |
          go install .github/workflows/vettools/atomicalign.go
          go vet -vettool=$(which atomicalign)${{ startsWith(matrix.os, 'windows-') && '.exe' || '' }} -tags=example -v ./...

      - name: go build
        run: |
          go build -tags=example -v ./...
          # Compile without optimization to check potential stack overflow.
          # The option '-gcflags=all=-N -l' is often used at Visual Studio Code.
          # See also https://go.googlesource.com/vscode-go/+/HEAD/docs/debugging.md#launch and the issue #2120.
          go build -tags=example "-gcflags=all=-N -l" -v ./...
          env GOOS=js GOARCH=wasm go build -tags=example -v ./...
          env GOOS=windows GOARCH=amd64 go build -tags=example -v ./...
          env GOOS=windows GOARCH=386 go build -tags=example -v ./...

      - name: go build (macOS)
        if: ${{ startsWith(matrix.os, 'macos-') && !startsWith(matrix.go, '1.15.') }}
        run: |
          env CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -tags=example -v ./...
          env CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -tags=example -o flappy_amd64 -v ./examples/flappy
          env CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -tags=example -o flappy_arm64 -v ./examples/flappy
          lipo -create flappy_amd64 flappy_arm64 -output flappy
          file flappy
          rm flappy

      - name: go build (cbackend)
        if: ${{ !startsWith(matrix.os, 'windows-') }}
        run: |
          go build -tags=example,ebitencbackend -v ./...

      - name: go test
        # TODO: Add more test environments (#1305)
        if: ${{ startsWith(matrix.os, 'ubuntu-') || startsWith(matrix.os, 'windows-') }}
        run: |
          go test -tags=example ${{ !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') && '-shuffle=on' || '' }} -v ./...

      - name: go test (Linux 386)
        if: ${{ startsWith(matrix.os, 'ubuntu-') }}
        run: |
          sudo dpkg --add-architecture i386
          sudo apt-get update
          sudo apt-get install gcc-multilib
          sudo apt-get install libasound2-dev:i386 libgl1-mesa-dev:i386 libxcursor-dev:i386 libxi-dev:i386 libxinerama-dev:i386 libxrandr-dev:i386 libxxf86vm-dev:i386
          env CGO_ENABLED=1 GOARCH=386 go test -tags=example ${{ !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') && '-shuffle=on' || '' }} -v ./...

      - name: go test (Windows 386)
        if: ${{ startsWith(matrix.os, 'windows-') }}
        run: |
          # TODO: Enable this after DirectX is supported on 32bit machines (#2088)
          # env GOARCH=386 go test -tags=example ${{ !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') && '-shuffle=on' || '' }} -v ./...

      - name: go test (Wasm)
        # TODO: Investigate times out on Windows. (#1313)
        if: ${{ !startsWith(matrix.os, 'windows-') && !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') }}
        run: |
          # TODO: Add -shuffle=on after agnivade/wasmbrowsertest#23 is fixed.
          env GOOS=js GOARCH=wasm go test -tags=example -v ./...
          env GOOS=js GOARCH=wasm go test -tags=example,ebitenwebgl1 -v ./...

      - name: Install ebitenmobile
        run: |
          go install ./cmd/ebitenmobile

      - name: ebitenmobile bind (Android)
        if: ${{ !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') }}
        run: |
          cd /tmp/go-inovation
          ebitenmobile bind -target android -javapkg com.hajimehoshi.goinovation -o inovation.aar -v github.com/hajimehoshi/go-inovation/mobile

      - name: ebitenmobile bind (iOS)
        if: ${{ startsWith(matrix.os, 'macos-') && !startsWith(matrix.go, '1.15.') && !startsWith(matrix.go, '1.16.') }}
        run: |
          cd /tmp/go-inovation
          ebitenmobile bind -target ios -o Inovation.xcframework -v github.com/hajimehoshi/go-inovation/mobile