techiferous/tabulous

View on GitHub
lib/tabulous/dsl/tabs.rb

Summary

Maintainability
A
1 hr
Test Coverage
module Tabulous
  module Dsl
    class Tabs
      class << self

        def process(&block)
          @tabset = Tabset.new
          @parent_tab = nil
          instance_exec(&block)
          check_for_errors!
          @tabset
        end

        def method_missing(method, *args, &block)
          method_name = method.to_s
          if method_name =~ /^(.+)_subtab/
            if @parent_tab.nil?
              raise SubtabOutOfOrderError, "You cannot start a tabs declaration with a subtab: '#{method_name}'."
            end
            tab = Dsl::Tab.process($1, @parent_tab, &block)
          elsif method_name =~ /^(.+)_tab/
            tab = Dsl::Tab.process($1, nil, &block)
            @parent_tab = tab
          else
            raise TabNameError, "Incorrect tab name: '#{method_name}'.  Tab names must end with _tab or _subtab."
          end
          @tabset.add_tab(tab)
        end

      private

        def check_for_errors!
          check_for_missing_subtab_declaration
          check_for_conflicting_active_actions
        end

        def check_for_missing_subtab_declaration
          for tab in @tabset.primary_tabs
            if !tab.subtabs.empty? && tab.declared_to_have_subtabs == false
              raise MissingActiveTabRuleError, "The tab '#{tab.name}' has subtabs but is missing the 'a_subtab_is_active' rule in its active_when declaration."
            end
          end
        end

        def check_for_conflicting_active_actions
          for tab in @tabset.tabs
            for other_tab in @tabset.tabs
              next if tab == other_tab
              if tab.active_actions_overlap?(other_tab)
                raise AmbiguousActiveTabRulesError, "Ambiguous declaration: the active_when rules in the tab #{tab.name} conflict with the active_when rules in the tab #{other_tab.name}."
              end
            end
          end
        end

      end
    end
  end
end