Skip to content

Commit

Permalink
Sets up spec to generate files using Elixir
Browse files Browse the repository at this point in the history
This adds necessary dependencies to the Spec package to begin generating
the language specs in Elixir using Liquid.
  • Loading branch information
johnnyt committed Apr 26, 2020
1 parent 7e358f5 commit d419998
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 17 deletions.
51 changes: 36 additions & 15 deletions bin/setup
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,68 @@ export OQ_VERSION="1.0.2"

# Setup ASDF version manager and install deps
setup_asdf() {
_info_banner "[ASDF] Setting up"
local prefix="[ASDF]"

_info_banner "${prefix} Setting up"

# Version manager for multiple languages
_prompt_for_command_install "asdf"

_info_message "Installing/Updating ASDF dependencies"
(asdf install && _success_message "Success - ASDF dependencies up to date") || \
_error_message "Failed to update ASDF dependencies"
(asdf install && _success_message "${prefix} Success: dependencies up to date") || \
_error_message "${prefix} Failed to update dependencies"
}

# Setup Ruby dependencies (used for Danger and generating templated specs)
setup_ruby() {
local prefix="[Ruby]"

_info_banner "${prefix} Setting up"

_info_message "${prefix} Installing/Updating RubyGems"
(bundle install && _success_message "${prefix} Success: RubyGems up to date") || \
_error_message "${prefix} Failed to update RubyGems"
}

_elixir_update() {
local subpath="${1?}"
local prefix="[${subpath}]"

# Setup dependencies for Elixir
setup_elixir() {
_info_banner "[Elixir] Setting up"
pushd statifier-ex 1>/dev/null
_info_banner "${prefix} Updating Elixir dependencies"

pushd "${subpath}" 1>/dev/null
# shellcheck disable=SC1010
mix do deps.get, compile

popd 1>/dev/null
_success_message "[Elixir] All up to date!"

_success_message "${prefix} Success: Elixir dependencies up to date"
}

# Setup dependencies for statifier-ex
setup_statifier_ex() {
_elixir_update statifier-ex
}

# Setup dependencies for Spec
setup_spec() {
_info_banner "[Spec] Setting up"
_elixir_update spec

# Working with YAML, XML and JSON files
_prompt_for_oq_install

_success_message "[Spec] All up to date!"
# # Working with YAML, XML and JSON files
# _prompt_for_oq_install
}


# Setup entire project. First global dependencies, then each package.
setup_project() {
_info_banner "Setting up Statifier"

# Global Setup
setup_asdf
setup_ruby

# Package specific
setup_spec
setup_elixir
setup_statifier_ex

_success_banner "Project successfully setup"
}
Expand Down
11 changes: 11 additions & 0 deletions bin/spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

set -u # raise an error on use of uninitialized variable
set -e # exit after the first error

# Wrapper around using the spec/Makefile using make v4

trap "popd 1>/dev/null" EXIT
pushd "spec" 1> /dev/null

gmake "$@"
19 changes: 17 additions & 2 deletions spec/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,28 @@ endif
.DEFAULT_GOAL := help

help: ## Displays help message describing each task
> @foo="bar"
> @printf "\n%s\n\n" "Statifier Spec Make Tasks"
> @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-${HELP_TASK_WIDTH}s\033[0m %s\n", $$1, $$2}'
> @printf "\n%s" "${foo}"
# Don't look for this on the filesystem
.PHONY: help

generate: generated/.elixir ## Generate all specs
> @echo "Done!"
# Don't look for this on the filesystem
.PHONY: generate

generated/.elixir: generated/
> @mix run generate.exs elixir $@

generated/:
> @mkdir -p generated

# w3c/.manifest: w3c/manifest.xml w3c_manifest.exs
# > @mix run w3c_manifest.exs w3c/manifest.xml $@ $(W3C_SUITE)

clean: ## Cleanup (remove) all generated files.
> @rm -rf generated

collect: $(shell find . -type d | grep '[0-9][0-9][0-9]' | awk '{printf $1 "/all.yml"}') ## Collect all sub specs into the **/*__all.yml file
> @echo
> @echo "hi"
Expand Down
12 changes: 12 additions & 0 deletions spec/generate.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule SpecGenerator do
def process(language, touchfile) do
full_touchfile = Path.expand(touchfile, ".")

IO.puts("Hi from Elixir: #{language} #{full_touchfile}")

File.touch!(full_touchfile)
end
end

[language, touchfile] = System.argv()
SpecGenerator.process(language, touchfile)
45 changes: 45 additions & 0 deletions spec/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
defmodule Statifier.MixProject do
use Mix.Project

def project do
[
app: :statifier_spec,
version: "0.1.0",
elixir: "~> 1.8",
start_permanent: Mix.env() == :prod,
docs: [extras: ["README.md"]],
description: description(),
# package: package(),
deps: deps()
]
end

def description, do: "Statifier Spec Generator"

# def package do
# [
# name: :statifier_spec,
# maintainers: ["JohnnyT"],
# licenses: ["MIT"],
# docs: [extras: ["README.md"]],
# links: %{"GitHub" => "https://github.com/riddler/statifier-ex"}
# ]
# end

# # Run "mix help compile.app" to learn about applications.
# def application do
# [
# extra_applications: [:logger]
# ]
# end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:credo, "~> 1.4", only: [:dev, :test], runtime: false},
{:ex_doc, ">= 0.0.0", only: :dev},
{:liquid, "~> 0.9"},
{:yaml_elixir, "~> 2.4"}
]
end
end
25 changes: 25 additions & 0 deletions spec/mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"credo": {:hex, :credo, "1.4.0", "92339d4cbadd1e88b5ee43d427b639b68a11071b6f73854e33638e30a0ea11f5", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1fd3b70dce216574ce3c18bdf510b57e7c4c85c2ec9cad4bff854abaf7e58658"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
"ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"},
"gettext": {:hex, :gettext, "0.17.4", "f13088e1ec10ce01665cf25f5ff779e7df3f2dc71b37084976cf89d1aa124d5c", [:mix], [], "hexpm", "3c75b5ea8288e2ee7ea503ff9e30dfe4d07ad3c054576a6e60040e79a801e14d"},
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e0100f8ef7d1124222c11ad362c857d3df7cb5f4204054f9f0f4a728666591fc"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"jason": {:hex, :jason, "1.2.0", "10043418c42d2493d0ee212d3fddd25d7ffe484380afad769a0a38795938e448", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "116747dbe057794c3a3e4e143b7c8390b29f634e16c78a7f59ba75bfa6852e7f"},
"liquid": {:hex, :liquid, "0.9.1", "eef4797f4b8b1cdd14c44d6dcd52bb49df9caf6bcf5dacfd61911fba8b6a628d", [:mix], [{:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "0472e078709036d0d31a82c6542d559cdad81552c40fb51745e108d4785db8df"},
"makeup": {:hex, :makeup, "1.0.1", "82f332e461dc6c79dbd82fbe2a9c10d48ed07146f0a478286e590c83c52010b5", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49736fe5b66a08d8575bf5321d716bac5da20c8e6b97714fec2bcd6febcfa1f8"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "f354efb2400dd7a80fd9eb6c8419068c4f632da4ac47f3d8822d6e33f08bc852"},
"tzdata": {:hex, :tzdata, "1.0.3", "73470ad29dde46e350c60a66e6b360d3b99d2d18b74c4c349dbebbc27a09a3eb", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a6e1ee7003c4d04ecbd21dd3ec690d4c6662db5d3bbdd7262d53cdf5e7c746c1"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
"yamerl": {:hex, :yamerl, "0.8.0", "8214cfe16bbabe5d1d6c14a14aea11c784b9a21903dd6a7c74f8ce180adae5c7", [:rebar3], [], "hexpm", "010634477bf9c208a0767dcca89116c2442cf0b5e87f9c870f85cd1c3e0c2aab"},
"yaml_elixir": {:hex, :yaml_elixir, "2.4.0", "2f444abc3c994c902851fde56b6a9cb82895c291c05a0490a289035c2e62ae71", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "4e25a6d5c873e393689c6f1062c5ec90f6cd1be2527b073178ae37eae4c78bee"},
}
69 changes: 69 additions & 0 deletions spec/templates/ex/statechart_test.exs.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# AUTOGENERATED FILE - DO NOT EDIT

defmodule Statifier.Spec.<%= spec.specid %>Test do
use ExUnit.Case, async: true

@moduletag spec_id: "<%= spec.specid %>"
@moduletag spec_group: "<%= spec.specgroup %>"
@moduletag spec_subject: "Statechart"
@moduletag spec_description: """
<%= spec.description %>
"""
@moduletag spec_statechart: <%= spec.statechart | elixir_map %>

{% comment %}
alias Statifier.Statechart
setup_all do
%{instructions: <%= instructions %>}
end
<% tests.each do |test| %>
test "<%= test["name"] %>", context do
predicate_context = <% if test["context"].nil? %>nil<% else %><%= elixir_hash test["context"] %><% end %>
expected_result = <% if test["result"].nil? %>nil<% else %><%= test["result"] %><% end %>
result = Predicator.Evaluator.execute context[:instructions], predicate_context
assert expected_result == result
#assert_empty e.stack
end
{% endcomment %}
<% end %>
end
{% comment %}
defmodule Statifier.Spec. do
use ExUnit.Case
alias Statifier.{Statechart, StateDef}
# Definied in test helper
alias Statifier.Spec
test "building basic statechart" do
test_path = Path.join(File.cwd!(), "test/fixtures/basic.yml")
{:ok, test_config} = YamlElixir.read_from_file(test_path)
sc = Statechart.build(test_config["statechart"])
assert %Statechart{
name: "Valid Single State",
states: [%StateDef{id: "greeting"} | _rest]
} = sc
end
# This corresponds to the <scxml> element defined here:
# https://www.w3.org/TR/scxml/#scxml
# A conformant SCXML document must have at least one <state>, <parallel> or
# <final> child.
test "conformance: at least one state" do
spec = Spec.from_fixture("basic.yml")
sc =
Statechart.build(spec.statechart)
|> Statechart.validate()
assert %Statechart{conformant: true} = sc
end
end
{% endcomment %}

0 comments on commit d419998

Please sign in to comment.