name: Tests

on:
  push:
    branches:
      - master
      - develop
  pull_request:
    types:
      - opened
      - synchronize

jobs:
  build_wo_default_features:
    name: Build without default features
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          override: true
      - name: Build ergotree-ir
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --no-default-features --manifest-path ergotree-ir/Cargo.toml
      - name: Build ergo-lib
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --no-default-features --manifest-path ergo-lib/Cargo.toml

  test:
    name: Tests on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macOS-latest]

    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions-rs/toolchain@v1
        with:
          override: true
      - name: cargo fetch
        uses: actions-rs/cargo@v1
        with:
          command: fetch
      - name: Build tests
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --verbose --release --tests
      - name: Run tests
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --verbose --release

  test_coverage:
    name: Code coverage in tests
    runs-on: ubuntu-latest
    container:
      image:                    xd009642/tarpaulin:latest
      options:                  --security-opt seccomp=unconfined
    steps:
      - name:                   Checkout repository
        uses:                   actions/checkout@v2
      - name:                   Generate code coverage
        run: |
          cargo tarpaulin --avoid-cfg-tarpaulin --timeout=360 -v --out Lcov --exclude-files 'bindings/**/*.*' --exclude-files 'ergo-rest/src/reqwest.rs' --exclude-files 'ergo-rest/src/reqwest/**/*.*' --exclude-files 'ergo-rest/src/wasm_timer.rs' --exclude-files 'ergo-rest/src/wasm_timer/**/*.*'
      - name: Push code coverage results to coveralls.io
        uses: coverallsapp/github-action@master
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          path-to-lcov: ./lcov.info

  clippy:
    name: Clippy (linter)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          components: clippy
          override: true
      - name: Check with Clippy
        uses: actions-rs/clippy-check@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          args: --all-features --all-targets -- -D warnings

  js_tests:
    name: Run JS tests and publish alpha versions
    runs-on: ubuntu-latest
    env:
      HAS_NPM_TOKEN: ${{ secrets.NPM_TOKEN != '' }}

    # Service containers to run `ergo` node in `devnet` mode
    services:
      # Label used to access the service container
      ergo_node:
        # Docker Hub image
        image: ergoplatform/ergo-devnet:latest
        ports:
          # Maps tcp port 9053 on service container to the host
          - 9053:9053
    
    steps:
      # Need the following command to get around a GA bug where the workspace can't be cleared due
      # to incorrect access permissions. This comes up due to the use of the service container
      # above. See https://github.com/actions/checkout/issues/211
      - name: set_file_permissions
        run: sudo chown -R $USER:$USER ${{ github.workspace }}

      - name: checkout
        uses: actions/checkout@v2

      - uses: actions-rs/toolchain@v1
        with:
          override: true

      - name: install deps
        run: |
          cd bindings/ergo-lib-wasm
          curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
          curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - 
          sudo apt-get -y install nodejs
      
      - name: run Wasm tests
        run: |
          cd bindings/ergo-lib-wasm
          wasm-pack build
          # wasm-pack test  --firefox --headless
          # wasm-pack test  --firefox --headless --release
          wasm-pack test  --chrome  --headless
          wasm-pack test  --chrome  --headless --release

      - name: run node JS tests
        run: |
          cd bindings/ergo-lib-wasm
          wasm-pack build
          npm install
          npm run test
      
      - name: run browser JS tests
        run: |
          cd bindings/ergo-lib-wasm
          wasm-pack build
          npm install
          npm run test-browser

      - name: build alpha versions
        run: |
          cd bindings/ergo-lib-wasm
          npm run build-nodejs-alpha
          npm run build-browser-alpha

      - name: publish nodejs alpha version to npm
        if: env.HAS_NPM_TOKEN == 'true'
        uses: JS-DevTools/npm-publish@v1
        with:
          token: ${{ secrets.NPM_TOKEN }}
          package: ./bindings/ergo-lib-wasm/pkg-nodejs/package.json
          tag: 'alpha'

      - name: publish browser alpha version to npm
        if: env.HAS_NPM_TOKEN == 'true'
        uses: JS-DevTools/npm-publish@v1
        with:
          token: ${{ secrets.NPM_TOKEN }}
          package: ./bindings/ergo-lib-wasm/pkg-browser/package.json
          tag: 'alpha'

  rustfmt:
    name: Code formatting (rustfmt)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          components: rustfmt
          override: true
      - name: Check formatting
        uses: actions-rs/cargo@v1
        with:
          command: fmt
          args: --all -- --check --color always

  doc-links:
    name: Check intra-documentation links
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          override: true
      - name: cargo fetch
        uses: actions-rs/cargo@v1
        with:
          command: fetch
      # Ensure intra-documentation links all resolve correctly
      # Requires #![deny(broken_intra_doc_links)] in crate.
      - name: Check intra-doc links
        uses: actions-rs/cargo@v1
        with:
          command: doc
          args: --document-private-items

  ios_tests:
    name: Test Swift(iOS) bindings
    runs-on: ubuntu-latest

    # Service containers to run `ergo` node in `devnet` mode
    services:
      # Label used to access the service container
      ergo_node:
        # Docker Hub image
        image: ergoplatform/ergo-devnet:latest
        ports:
          # Maps tcp port 9053 on service container to the host
          - 9053:9053

    steps:
      - uses: fwal/setup-swift@v1
      - name: checkout
        uses: actions/checkout@v2

      - uses: actions-rs/toolchain@v1
        with:
          toolchain: nightly-2023-05-17
          override: true

      - name: install deps
        run: cargo install cbindgen

      - name: generate C-bindings header file
        run: |
          cd bindings/ergo-lib-c
          cbindgen --config cbindgen.toml --crate ergo-lib-c --output h/ergo_lib.h

      - uses: actions-rs/toolchain@v1
        with:
          override: true

      - name: build and run tests
        run: |
          cargo build --all-features -p ergo-lib-c
          cd bindings/ergo-lib-ios
          swift test -Xlinker -L../../target/debug/

  android_tests:
    name: Test JNI(Android) bindings
    runs-on: macos-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2

      - uses: actions-rs/toolchain@v1
        with:
          override: true

      - name: install deps
        run: |
          rustup target add armv7-linux-androideabi   # for arm
          rustup target add i686-linux-android        # for x86
          rustup target add aarch64-linux-android     # for arm64
          rustup target add x86_64-linux-android      # for x86_64

      - name: run tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 29
          ndk: 21.3.6528147
          emulator-build: 6110076
          script: cd ./bindings/ergo-lib-jni && ./gradlew connectedCheck
