From 41c0d9abc74c124ba21f15d0d3b54dca6d839f75 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Wed, 19 Sep 2018 18:53:09 -0600 Subject: [PATCH] Initial changes for DSL refactor No examples are picked up right now. --- src/spectator/dsl/structure_dsl.cr | 191 ++++++----------------------- 1 file changed, 37 insertions(+), 154 deletions(-) diff --git a/src/spectator/dsl/structure_dsl.cr b/src/spectator/dsl/structure_dsl.cr index 1248ef5..f44bc35 100644 --- a/src/spectator/dsl/structure_dsl.cr +++ b/src/spectator/dsl/structure_dsl.cr @@ -9,70 +9,34 @@ module Spectator end macro context(what, type = "Context", &block) - {% - parent_module = @type - safe_name = what.id.stringify.chars.map { |c| ::Spectator::Definitions::SPECIAL_CHARS[c] || c }.join("").gsub(/\W+/, "_") - module_name = (type.id + safe_name.camelcase).id - absolute_module_name = [parent_module, module_name].join("::").id - what_arg = what.is_a?(StringLiteral) ? what : what.stringify - parent_def = ::Spectator::Definitions::ALL[parent_module.id] - parent_def[:children] << absolute_module_name + module {{type.id}}%context + include {{@type.id}} - ::Spectator::Definitions::ALL[absolute_module_name] = { - name: module_name, - parent: parent_module, - given: parent_def[:given].map { |e| e }, # Duplicate elements without dup method. - children: [] of Object - } - %} + ::Spectator::Definitions::MAPPING[\{{@type.stringify}}] = + ExampleGroup.new( + {{what.is_a?(StringLiteral) ? what : what.stringify}}, + ::Spectator::Definitions::MAPPING[{{@type.stringify}}] + ) - ::Spectator::Definitions::MAPPING[{{absolute_module_name.stringify}}] = - ExampleGroup.new({{what_arg}}, ::Spectator::Definitions::MAPPING[{{parent_module.stringify}}]) - - module {{module_name.id}} - include {{parent_module}} - - {% if what.is_a?(Path) || what.is_a?(Generic) %} - def described_class - {{what}}.tap do |thing| - raise "#{thing} must be a type name to use #described_class or #subject,\ - but it is a #{typeof(thing)}" unless thing.is_a?(Class) - end - end - - def subject - described_class.new - end - {% end %} + _described_class {{what}} {{block.body}} end end macro given(collection, &block) - {% parent_module = @type %} context({{collection}}, "Given") do - {% - var_name = block.args.empty? ? "value".id : block.args.first - given_vars = ::Spectator::Definitions::ALL[parent_module.id][:given] - if given_vars.find { |v| v[:name] == var_name.id } - raise "Duplicate given variable name \"#{var_name.id}\"" - end - %} - - def self.%collection + def %collection {{collection}} end - def self.%first + def %first %collection.first end - \{% ::Spectator::Definitions::ALL[@type.id][:given] << { - name: "{{var_name}}".id, - collection: "{{collection}}".id, - type_def: (@type.id + '.' + :%first.stringify[1..-1]).id - } %} + def {{block.args.empty? ? "value".id : block.args.first}} + nil # TODO + end {{block.body}} end @@ -129,132 +93,51 @@ module Spectator end macro it(description, &block) - {% - parent_module = @type - safe_name = description.id.stringify.chars.map { |c| ::Spectator::Definitions::SPECIAL_CHARS[c] || c }.join("").gsub(/\W+/, "_") - class_name = (safe_name.camelcase + "Example").id - absolute_class_name = [parent_module.id, class_name].join("::").id - parent_def = ::Spectator::Definitions::ALL[parent_module.id] - given_vars = parent_def[:given] - var_names = given_vars.map { |v| v[:name] } - parent_def[:children] << absolute_class_name - %} - class Example%example include ::Spectator::DSL::ExampleDSL - include {{parent_module}} + include {{@type.id}} - def %run({{ var_names.join(", ").id }}) + def %run {{block.body}} end end - class {{class_name.id}} < ::Spectator::RunnableExample - {% for given_var, i in given_vars %} - @%var{i} : ValueWrapper - - private def %var{i} - @%var{i}.unsafe_as(TypedValueWrapper(typeof({{given_var[:type_def]}}))).value - end - {% end %} - - def initialize(group{% for v, i in var_names %}, %var{i}{% end %}) - super(group) - {% for given_var, i in given_vars %} - @%var{i} = TypedValueWrapper(typeof({{given_var[:type_def]}})).new(%var{i}) - {% end %} - end - + class Wrapper%wrapper < ::Spectator::RunnableExample protected def run_instance - Example%example.new.%run({% for v, i in var_names %}%var{i}{% if i < var_names.size - 1 %}, {% end %}{% end %}) + Example%example.new.%run end def description - {% if description.is_a?(StringLiteral) %} - {{description}} - {% else %} - {{description.stringify}} - {% end %} + {{description.is_a?(StringLiteral) ? description : description.stringify}} end end - - %current_group = ::Spectator::Definitions::MAPPING[{{parent_module.stringify}}] - {% for given_var, i in given_vars %} - {% - var_name = given_var[:name] - collection = given_var[:collection] - %} - {{collection}}.each do |%var{i}| - {% end %} - %current_group.examples << {{class_name.id}}.new(%current_group {% for v, i in var_names %}, %var{i}{% end %}) - {% for given_var in given_vars %} - end - {% end %} end macro pending(description, &block) - {% - parent_module = @type - safe_name = description.id.stringify.chars.map { |c| ::Spectator::Definitions::SPECIAL_CHARS[c] || c }.join("").gsub(/\W+/, "_") - class_name = (safe_name.camelcase + "Example").id - absolute_class_name = [parent_module.id, class_name].join("::").id - parent_def = ::Spectator::Definitions::ALL[parent_module.id] - given_vars = parent_def[:given] - var_names = given_vars.map { |v| v[:name] } - parent_def[:children] << absolute_class_name - %} - - class Example%example - include ::Spectator::DSL::ExampleDSL - include {{parent_module}} - - def %run({{ var_names.join(", ").id }}) - {{block.body}} - end - end - - class {{class_name.id}} < ::Spectator::PendingExample - {% for given_var, i in given_vars %} - @%var{i} : ValueWrapper - - private def %var{i} - @%var{i}.unsafe_as(TypedValueWrapper(typeof({{given_var[:type_def]}}))).value - end - {% end %} - - def initialize(group{% for v, i in var_names %}, %var{i}{% end %}) - super(group) - {% for given_var, i in given_vars %} - @%var{i} = TypedValueWrapper(typeof({{given_var[:type_def]}})).new(%var{i}) - {% end %} - end - - def description - {% if description.is_a?(StringLiteral) %} - {{description}} - {% else %} - {{description.stringify}} - {% end %} - end - end - - %current_group = ::Spectator::Definitions::MAPPING[{{parent_module.stringify}}] - {% for given_var, i in given_vars %} - {% - var_name = given_var[:name] - collection = given_var[:collection] - %} - {{collection}}.each do |%var{i}| - {% end %} - %current_group.examples << {{class_name.id}}.new(%current_group {% for v, i in var_names %}, %var{i}{% end %}) - {% for given_var in given_vars %} - end - {% end %} end def it_behaves_like raise NotImplementedError.new("Spectator::DSL#it_behaves_like") end + + macro _described_class(what) + {% if what.is_a?(Path) || what.is_a?(Generic) %} + def described_class + {{what}}.tap do |thing| + raise "#{thing} must be a type name to use #described_class or #subject,\ + but it is a #{typeof(thing)}" unless thing.is_a?(Class) + end + end + + _implicit_subject + {% end %} + end + + macro _implicit_subject + def subject + described_class.new + end + end end end end