diff --git a/lib/webspicy/cmd.rb b/lib/webspicy/cmd.rb new file mode 100644 index 0000000..737698e --- /dev/null +++ b/lib/webspicy/cmd.rb @@ -0,0 +1,45 @@ +module Webspicy + module Cmd + + require_relative 'cmd/specification' + + FORMALDOC = Finitio.system(Path.dir/("cmd/formaldoc.fio")) + + def specification(raw, file = nil, scope = Webspicy.default_scope) + raw = YAML.load(raw) if raw.is_a?(String) + Webspicy.with_scope(scope) do + r = FORMALDOC["Specification"].dress(raw) + r.config = scope.config + r.located_at!(file) if file + r + end + rescue Finitio::Error => ex + handle_finitio_error(ex) + end + module_function :specification + + def service(raw, scope = Webspicy.default_scope) + Webspicy.with_scope(scope) do + FORMALDOC["Service"].dress(raw) + end + rescue Finitio::Error => ex + handle_finitio_error(ex) + end + module_function :service + + def test_case(raw, scope = Webspicy.default_scope) + Webspicy.with_scope(scope) do + FORMALDOC["TestCase"].dress(raw) + end + rescue Finitio::Error => ex + handle_finitio_error(ex) + end + module_function :test_case + + def handle_finitio_error(ex) + raise ex + end + module_function :handle_finitio_error + + end # module Cmd +end # module Webspicy diff --git a/lib/webspicy/cmd/formaldoc.fio b/lib/webspicy/cmd/formaldoc.fio new file mode 100644 index 0000000..cd5984c --- /dev/null +++ b/lib/webspicy/cmd/formaldoc.fio @@ -0,0 +1,37 @@ +@import finitio/data +@import webspicy/shared + +Specification = .Webspicy::Cmd::Specification { + command : String + name :? String + description :? String + preconditions :? [String]|String + postconditions :? [String]|String + errconditions :? [String]|String + input_schema :? Schema + output_schema :? Schema + error_schema :? Schema + default_example :? TestCase + examples :? [TestCase] + counterexamples :? [TestCase] +} + +Service = .Webspicy::Cmd::Specification::Service { + description :? String + preconditions :? [String]|String + postconditions :? [String]|String + errconditions :? [String]|String + input_schema :? Schema + output_schema :? Schema + error_schema :? Schema + default_example :? TestCase + examples :? [TestCase] + counterexamples :? [TestCase] +} + +TestCase = .Webspicy::Cmd::Specification::TestCase { + description :? String + metadata :? { ...: .Object } + args :? [String] + assert :? { ...: .Object } +} diff --git a/lib/webspicy/cmd/specification.rb b/lib/webspicy/cmd/specification.rb new file mode 100644 index 0000000..30d8c25 --- /dev/null +++ b/lib/webspicy/cmd/specification.rb @@ -0,0 +1,38 @@ +module Webspicy + module Cmd + class Specification < Webspicy::Specification + + class << self + def info(raw) + new(raw) + end + + def singleservice(raw) + converted = { + name: raw[:name] || "Unamed specification", + command: raw[:command], + services: [ + Webspicy::Cmd.service(raw.reject{|k| k==:command or k==:name }, Webspicy.current_scope) + ] + } + info(converted) + rescue => ex + puts "Coucou: #{ex.message}" + puts ex.backtrace.join("\n") + raise + end + end + + def command + @raw[:command] + end + + def to_singleservice + raise NotImplementedError + end + + end # class Specification + end # module Cmd +end # module Webspicy +require_relative 'specification/service' +require_relative 'specification/test_case' diff --git a/lib/webspicy/cmd/specification/service.rb b/lib/webspicy/cmd/specification/service.rb new file mode 100644 index 0000000..6d6a232 --- /dev/null +++ b/lib/webspicy/cmd/specification/service.rb @@ -0,0 +1,8 @@ +module Webspicy + module Cmd + class Specification + class Service < Webspicy::Specification::Service + end # class Service + end # class Specification + end # module Web +end # module Webspicy diff --git a/lib/webspicy/cmd/specification/test_case.rb b/lib/webspicy/cmd/specification/test_case.rb new file mode 100644 index 0000000..1c48849 --- /dev/null +++ b/lib/webspicy/cmd/specification/test_case.rb @@ -0,0 +1,8 @@ +module Webspicy + module Cmd + class Specification + class TestCase < Webspicy::Specification::TestCase + end # class TestCase + end # class Specification + end # module Web +end # module Webspicy diff --git a/lib/webspicy/specification/service.rb b/lib/webspicy/specification/service.rb index 914cd05..ce7c1ff 100644 --- a/lib/webspicy/specification/service.rb +++ b/lib/webspicy/specification/service.rb @@ -86,10 +86,6 @@ def dress_params(params) input_schema.dress(params) end - def to_s - "#{method} #{specification.url}" - end - private def compile_preconditions diff --git a/lib/webspicy/web/specification/service.rb b/lib/webspicy/web/specification/service.rb index d6c1bd4..8f104ab 100644 --- a/lib/webspicy/web/specification/service.rb +++ b/lib/webspicy/web/specification/service.rb @@ -7,6 +7,10 @@ def method @raw[:method] end + def to_s + "#{method} #{specification.url}" + end + end # class Service end # class Specification end # module Web diff --git a/spec/cmd/config.rb b/spec/cmd/config.rb new file mode 100644 index 0000000..e5688bb --- /dev/null +++ b/spec/cmd/config.rb @@ -0,0 +1,5 @@ +require 'webspicy/cmd' + +Webspicy::Configuration.new(Path.dir) do |c| + c.factory = Webspicy::Cmd +end diff --git a/spec/cmd/formalspec/base.yml b/spec/cmd/formalspec/base.yml new file mode 100644 index 0000000..16991a8 --- /dev/null +++ b/spec/cmd/formalspec/base.yml @@ -0,0 +1,25 @@ +--- +command: + webspicy {options} {args} + +examples: + +- description: |- + when called on a passing path + args: + - examples/website/get-http.yml + assert: + exit_code: + 0 + stdout: |- + >> specification/get-http.yml + + GET http://yourbackendisbroken.dev, it works + v It has a 300 response status + v It has a `Content-Type: text/html` response header + v It has a `Location: https://yourbackendisbroken.dev/?id=1` response header + v Its output meets the expected data schema + + + 1 spec file, 1 example, 0 counterexample + 4 assertions, 0 error, 0 failure