Skip to content

Commit

Permalink
Create feature tests for examples (#9)
Browse files Browse the repository at this point in the history
* Add GitHub action
* Create docker testing containers for
  * todos scaffold 
  * todos hotwire 
  * todos api 
* Add unit tests
  • Loading branch information
AlexB52 authored Apr 17, 2024
1 parent 65ca1b1 commit 6b71194
Show file tree
Hide file tree
Showing 26 changed files with 1,229 additions and 6 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby

name: Ruby

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
unit-tests:
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- run: bundle install
- run: bundle exec rake

app-tests:
name: ${{ matrix.repo }} feature specs
runs-on: ubuntu-latest
strategy:
matrix:
repo:
- todos-scaffold
- todos-hotwire
- todos-api
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- run: bin/test/${{ matrix.repo }}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
/pkg/
/spec/reports/
/tmp/
examples/*.sqlite*
examples/*.sqlite*
**/*.sqlite*
log/*
**/uni_rails.gem
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ source "https://rubygems.org"
gemspec

gem "rake", "~> 13.0"

gem "minitest", "~> 5.0"
gem "rack-test"
gem "debug"
gem "sqlite3"
gem "puma"
18 changes: 18 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ GEM
connection_pool (2.4.1)
crass (1.0.6)
date (3.3.4)
debug (1.9.2)
irb (~> 1.10)
reline (>= 0.3.8)
drb (2.2.1)
erubi (1.12.0)
globalid (1.2.1)
Expand Down Expand Up @@ -120,10 +123,16 @@ GEM
net-smtp (0.5.0)
net-protocol
nio4r (2.7.1)
nokogiri (1.16.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.3-x86_64-linux)
racc (~> 1.4)
psych (5.1.2)
stringio
puma (6.4.2)
nio4r (~> 2.0)
racc (1.7.3)
rack (3.0.10)
rack-session (2.0.0)
Expand Down Expand Up @@ -167,6 +176,9 @@ GEM
psych (>= 4.0.0)
reline (0.5.0)
io-console (~> 0.5)
sqlite3 (1.7.3-arm64-darwin)
sqlite3 (1.7.3-x86_64-darwin)
sqlite3 (1.7.3-x86_64-linux)
stringio (3.1.0)
thor (1.3.1)
timeout (0.4.1)
Expand All @@ -179,11 +191,17 @@ GEM
zeitwerk (2.6.13)

PLATFORMS
arm64-darwin-23
x86_64-darwin-21
x86_64-linux

DEPENDENCIES
debug
minitest (~> 5.0)
puma
rack-test
rake (~> 13.0)
sqlite3
uni_rails!

BUNDLED WITH
Expand Down
6 changes: 6 additions & 0 deletions bin/test/todos-api
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

bundle install
bundle exec rake build
ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/todos-api/uni_rails.gem
docker-compose -f features/todos-api/docker-compose.yml up --build --exit-code-from test
6 changes: 6 additions & 0 deletions bin/test/todos-hotwire
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

bundle install
bundle exec rake build
ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/todos-hotwire/uni_rails.gem
docker-compose -f features/todos-hotwire/docker-compose.yml up --build --exit-code-from test
6 changes: 6 additions & 0 deletions bin/test/todos-scaffold
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

bundle install
bundle exec rake build
ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/todos-scaffold/uni_rails.gem
docker-compose -f features/todos-scaffold/docker-compose.yml up --build --exit-code-from test
Binary file added features/todos-api/.DS_Store
Binary file not shown.
22 changes: 22 additions & 0 deletions features/todos-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM ruby:3.3.0-slim-bullseye

ARG BUILD_PACKAGES="build-essential git curl libvips pkg-config sqlite3 libsqlite3-dev"

# Install packages needed to build gems
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y $BUILD_PACKAGES

WORKDIR /usr/src/app

ENV LANG C.UTF-8
ENV BUNDLER_VERSION 2.1
ENV GEM_HOME="/usr/local/bundle"
ENV PATH $GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH

COPY Gemfile uni_rails.gem ./
RUN gem install uni_rails.gem
RUN bundle install

COPY . /usr/src/app

CMD ["ruby", "app.rb"]
13 changes: 13 additions & 0 deletions features/todos-api/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

source "https://rubygems.org"

gem 'uni_rails', path: '/usr/local/bundle'
gem "sqlite3"
gem "puma"

# Test
gem "capybara", "~> 3.40"
gem "selenium-webdriver", "~> 4.19"
gem "minitest"
gem "debug"
97 changes: 97 additions & 0 deletions features/todos-api/app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require 'uni_rails'
require "rack/handler/puma"
require 'debug'
require 'sqlite3'

ENV['DATABASE_URL'] = "sqlite3:///#{__dir__}/database.sqlite"

ActiveRecord::Base.establish_connection
ActiveRecord::Schema.define do
create_table :todos, force: :cascade do |t|
t.string :name
t.datetime :completed_at
t.timestamps
end
end

UniRails::App.routes.append do
resources :todos do
put :complete, on: :member
end
end

# MODELS

class Todo < ActiveRecord::Base
validates :name, presence: true

def complete(at: Time.zone.now)
update(completed_at: at)
end
end

# CONTROLLERS

class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
end

class TodosController < ApplicationController
before_action :set_todo, only: [:show, :update, :destroy, :complete]

def index
@todos = Todo.all
render json: @todos
end

def show
render json: @todo
end

def create
@todo = Todo.new(todo_params)
if @todo.save
render json: @todo, status: :created, location: @todo
else
render json: @todo.errors, status: :unprocessable_entity
end
end

def update
if @todo.update(todo_params)
render json: @todo
else
render json: @todo.errors, status: :unprocessable_entity
end
end

def complete
if @todo.complete
render json: @todo
else
render json: @todo.errors, status: :unprocessable_entity
end
end

def destroy
@todo.destroy
head :no_content
end

private

def set_todo
@todo = Todo.find(params[:id])
end

def todo_params
params.require(:todo).permit(:name, :status)
end
end

UniRails::App.configure do
config.log_level = :error
config.hosts << ENV['APP_HOST']
end

UniRails.run(Port: 3000)
71 changes: 71 additions & 0 deletions features/todos-api/app_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require "capybara"
require "capybara/dsl"
require 'capybara/minitest'
require "selenium-webdriver"
require "minitest/autorun"
require "debug"

APP_HOST = ENV.fetch('APP_HOST')

def truncate_tables
require "sqlite3"
SQLite3::Database.new( "database.sqlite" ) do |db|
db.execute("DELETE FROM todos")
end
end

class Client
def initialize(url)
@uri = URI(url)
end

def get(url)
start do |http|
http.get(url)
end
end

def post(url, params)
start do |http|
http.post(url, params.to_json, "Content-Type" => "application/json")
end
end

def delete(url)
start do |http|
http.delete(url)
end
end

def start
Net::HTTP.start(@uri.hostname, @uri.port) do |http|
yield http
end
end
end

class TestJSONTodos < Minitest::Test
def setup
@client = Client.new(APP_HOST)
truncate_tables
end

def test_create_a_new_todo
response = @client.get('/todos.json')
todos = JSON.parse(response.body)
assert_equal 0, todos.length

response = @client.post '/todos.json', { todo: { name: 'Buy milk' } }
todo = JSON.parse(response.body)

response = @client.get('/todos.json')
todos = JSON.parse(response.body)
assert_equal 1, todos.length

@client.delete("/todos/#{todo['id']}.json")

response = @client.get('/todos.json')
todos = JSON.parse(response.body)
assert_equal 0, todos.length
end
end
28 changes: 28 additions & 0 deletions features/todos-api/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: '3'

services:
uni_rails:
build: .
ports:
- 127.0.0.1:3000:3000
volumes:
- .:/usr/src/app
environment:
- APP_HOST=uni_rails:3000
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000 || exit 1"]
interval: 3s
timeout: 5s
retries: 3
start_period: 5s
command: ruby app.rb
test:
build: .
volumes:
- .:/usr/src/app
environment:
- APP_HOST=http://uni_rails:3000
depends_on:
uni_rails:
condition: service_healthy
command: ruby app_test.rb
Loading

0 comments on commit 6b71194

Please sign in to comment.