include YARD::Templates::Helpers::HtmlHelper def init super # Additional javascript that power the additional menus, collapsing, etc. asset "js/cucumber.js", file("js/cucumber.js",true) serialize_object_type :feature serialize_object_type :tag # Generates the requirements splash page with the 'requirements' template serialize(YARD::CodeObjects::Cucumber::CUCUMBER_NAMESPACE) # Generates a page for step definitions and step placeholders with the 'steptransformers' template serialize(YARD::CodeObjects::Cucumber::CUCUMBER_STEPTRANSFORM_NAMESPACE) # Generates the tags page with the 'featuretags' template serialize(YARD::CodeObjects::Cucumber::CUCUMBER_TAG_NAMESPACE) serialize_feature_directories end # # The top-level feature directories. This is affected by the directories that YARD is told to parse. # All other features in sub-directories are contained under each of these top-level directories. # # @example Generating one feature directory # # `yardoc 'example/**/*'` # # @example Generating two feature directories # # `yardoc 'example/**/*' 'example2/**/*'` # # @return the feature directories at the root of the Cucumber Namespace. # def root_feature_directories @root_feature_directories ||= YARD::CodeObjects::Cucumber::CUCUMBER_NAMESPACE.children.find_all {|child| child.is_a?(YARD::CodeObjects::Cucumber::FeatureDirectory)} end # # Generate pages for the objects if there are objects of this type contained # within the Registry. # def serialize_object_type(type) objects = Registry.all(type.to_sym) Array(objects).each {|object| serialize(object) } end # # Generates pages for the feature directories found. Starting with all root-level feature # directories and then recursively finding all child feature directories. # def serialize_feature_directories serialize_feature_directories_recursively(root_feature_directories) root_feature_directories.each {|directory| serialize(directory) } end # # Generate a page for each Feature Directory. This is called recursively to # ensure that all feature directories contained as children are rendered to # pages. # def serialize_feature_directories_recursively(namespaces) namespaces.each do |namespace| Templates::Engine.with_serializer(namespace, options[:serializer]) do options[:object] = namespace T('layout').run(options) end serialize_feature_directories_recursively(namespace.children.find_all {|child| child.is_a?(YARD::CodeObjects::Cucumber::FeatureDirectory)}) end end # Generate feature list # @note this method is called automatically by YARD based on the menus defined in the layout def generate_feature_list features = Registry.all(:feature) features_ordered_by_name = features.sort {|x,y| x.value.to_s <=> y.value.to_s } generate_full_list features_ordered_by_name, :features end # Count scenarios for features def record_feature_scenarios(features) count_with_examples = 0 features.each do |f| count_with_examples += f.total_scenarios end return count_with_examples end # Count scenarios for tags def record_tagged_scenarios(tags) scenario_count = 0 count_with_examples = 0 tags.each do |t| scenario_count += t.all_scenarios.size count_with_examples += t.total_scenarios end end # Generate tag list # @note this method is called automatically by YARD based on the menus defined in the layout def generate_tag_list tags = Registry.all(:tag) tags_ordered_by_use = Array(tags).sort {|x,y| y.total_scenarios <=> x.total_scenarios } record_tagged_scenarios(tags) generate_full_list tags_ordered_by_use, :tags end # Generate a step definition list # @note this menu is not automatically added until yard configuration has this menu added # See the layout template method that loads the menus def generate_stepdefinition_list generate_full_list YARD::Registry.all(:stepdefinition), :stepdefinitions, :list_title => "Step Definitions List" end # Generate a step list # @note this menu is not automatically added until yard configuration has this menu added # See the layout template method that loads the menus def generate_step_list generate_full_list YARD::Registry.all(:step), :steps end # Generate feature list # @note this menu is not automatically added until yard configuration has this menu added # See the layout template method that loads the menus def generate_featuredirectories_list directories_ordered_by_name = root_feature_directories.sort {|x,y| x.value.to_s <=> y.value.to_s } generate_full_list directories_ordered_by_name, :featuredirectories, :list_title => "Features by Directory", :list_filename => "featuredirectories_list.html" end # Helpler method to generate a full_list page of the specified objects with the # specified type. def generate_full_list(objects,type,options = {}) defaults = { :list_title => "#{type.to_s.capitalize} List", :css_class => "class", :list_filename => "#{type.to_s.gsub(/s$/,'')}_list.html" } options = defaults.merge(options) @items = objects @list_type = type @list_title = options[:list_title] @list_class = options[:css_class] asset options[:list_filename], erb(:full_list) end # # @note This method overrides YARD's default template class_list method. # # The existing YARD 'Class List' search field contains all the YARD namespace objects. # We, however, do not want the Cucumber Namespace YARD Object (which holds the features, # tags, etc.) as it is a meta-object. # # This method removes the namespace from the root node, generates the class list, # and then adds it back into the root node. # def class_list(root = Registry.root, tree = TreeContext.new) return super unless root == Registry.root cucumber_namespace = YARD::CodeObjects::Cucumber::CUCUMBER_NAMESPACE root.instance_eval { children.delete cucumber_namespace } out = super(root) root.instance_eval { children.push cucumber_namespace } out end # # Generate a link to the 'All Features' in the features_list.html # # When there are no feature directories or multiple top-level feature directories # then we want to link to the 'Requirements' page # # When there are is just one feature directory then we want to link to that directory # def all_features_link features = Registry.all(:feature) count_with_examples = record_feature_scenarios(features) if root_feature_directories.length == 0 || root_feature_directories.length > 1 linkify YARD::CodeObjects::Cucumber::CUCUMBER_NAMESPACE, "All Features (#{count_with_examples})" else linkify root_feature_directories.first, "All Features (#{count_with_examples})" end end # # This method is used to generate a feature directory. This template may call # this method as well to generate any child feature directories as well. # # @param directory [FeatureDirectory] this is the FeatureDirectory to display # @param padding [Fixnum] this is the pixel value to ident as we want to keep # pushing in the padding to show the parent relationship # @param row [String] 'odd' or 'even' to correctly color the row # def directory_node(directory,padding,row) @directory = directory @padding = padding @row = row erb(:directories) end