diff --git a/lib/puppet-strings.rb b/lib/puppet-strings.rb index 31f633865..b8b84bb4d 100644 --- a/lib/puppet-strings.rb +++ b/lib/puppet-strings.rb @@ -6,6 +6,7 @@ module PuppetStrings functions/**/*.pp types/**/*.pp lib/**/*.rb + tasks/*.json ).freeze # Generates documentation. diff --git a/lib/puppet-strings/json.rb b/lib/puppet-strings/json.rb index ff85a7e5e..85491e55a 100644 --- a/lib/puppet-strings/json.rb +++ b/lib/puppet-strings/json.rb @@ -12,6 +12,7 @@ def self.render(file = nil) resource_types: YARD::Registry.all(:puppet_type).sort_by!(&:name).map!(&:to_hash), providers: YARD::Registry.all(:puppet_provider).sort_by!(&:name).map!(&:to_hash), puppet_functions: YARD::Registry.all(:puppet_function).sort_by!(&:name).map!(&:to_hash), + puppet_tasks: YARD::Registry.all(:puppet_task).sort_by!(&:name).map!(&:to_hash), # TODO: Need Ruby documentation? } diff --git a/lib/puppet-strings/markdown.rb b/lib/puppet-strings/markdown.rb index 637009998..e5b0d49d8 100644 --- a/lib/puppet-strings/markdown.rb +++ b/lib/puppet-strings/markdown.rb @@ -6,6 +6,7 @@ module PuppetStrings::Markdown require_relative 'markdown/functions' require_relative 'markdown/defined_types' require_relative 'markdown/resource_types' + require_relative 'markdown/puppet_tasks' require_relative 'markdown/table_of_contents' # generates markdown documentation @@ -17,6 +18,7 @@ def self.generate final << PuppetStrings::Markdown::DefinedTypes.render final << PuppetStrings::Markdown::ResourceTypes.render final << PuppetStrings::Markdown::Functions.render + final << PuppetStrings::Markdown::PuppetTasks.render final end diff --git a/lib/puppet-strings/markdown/puppet_task.rb b/lib/puppet-strings/markdown/puppet_task.rb new file mode 100644 index 000000000..60bd3c5b0 --- /dev/null +++ b/lib/puppet-strings/markdown/puppet_task.rb @@ -0,0 +1,24 @@ +require 'puppet-strings/markdown/base' + +module PuppetStrings::Markdown + class PuppetTask < Base + def initialize(registry) + @template = 'puppet_task.erb' + @registry = registry + super(registry, 'task') + end + + def render + super(@template) + end + + def supports_noop + @registry[:supports_noop] + end + + def input_method + @registry[:input_method] + end + + end +end diff --git a/lib/puppet-strings/markdown/puppet_tasks.rb b/lib/puppet-strings/markdown/puppet_tasks.rb new file mode 100644 index 000000000..c5e417ce4 --- /dev/null +++ b/lib/puppet-strings/markdown/puppet_tasks.rb @@ -0,0 +1,34 @@ +require_relative 'puppet_task' + +module PuppetStrings::Markdown + module PuppetTasks + + # @return [Array] list of classes + def self.in_tasks + arr = YARD::Registry.all(:puppet_task).sort_by!(&:name).map!(&:to_hash) + arr.map! { |a| PuppetStrings::Markdown::PuppetTask.new(a) } + end + + def self.contains_private? + false + end + + def self.render + final = in_tasks.length > 0 ? "## Tasks\n\n" : "" + in_tasks.each do |task| + final << task.render unless task.private? + end + final + end + + def self.toc_info + final = ["Tasks"] + + in_tasks.each do |task| + final.push(task.toc_info) + end + + final + end + end +end diff --git a/lib/puppet-strings/markdown/table_of_contents.rb b/lib/puppet-strings/markdown/table_of_contents.rb index ed230acc2..d88e223c2 100644 --- a/lib/puppet-strings/markdown/table_of_contents.rb +++ b/lib/puppet-strings/markdown/table_of_contents.rb @@ -6,7 +6,8 @@ def self.render [PuppetStrings::Markdown::PuppetClasses, PuppetStrings::Markdown::DefinedTypes, PuppetStrings::Markdown::ResourceTypes, - PuppetStrings::Markdown::Functions].each do |r| + PuppetStrings::Markdown::Functions, + PuppetStrings::Markdown::PuppetTasks].each do |r| toc = r.toc_info group_name = toc.shift group = toc diff --git a/lib/puppet-strings/markdown/templates/puppet_task.erb b/lib/puppet-strings/markdown/templates/puppet_task.erb new file mode 100644 index 000000000..5fbc53ef3 --- /dev/null +++ b/lib/puppet-strings/markdown/templates/puppet_task.erb @@ -0,0 +1,28 @@ +### <%= name %> + +<% if text -%> +<%= text %> + +<% elsif summary -%> +<%= summary %> + +<% else -%> +<%= "The #{name} task." %> + +<% end -%> +**Supports noop?** <%= supports_noop %> + +<% if params -%> +#### Parameters + +<% params.each do |param| -%> +##### `<%= param[:name] %>` + +<% if param[:types] -%> +Data type: `<%= param[:types].join(', ') -%>` + +<% end -%> +<%= param[:text] %> + +<% end -%> +<% end -%> diff --git a/lib/puppet-strings/yard.rb b/lib/puppet-strings/yard.rb index abba601b0..256b69bac 100644 --- a/lib/puppet-strings/yard.rb +++ b/lib/puppet-strings/yard.rb @@ -15,10 +15,12 @@ def self.setup! # Register the Puppet parser YARD::Parser::SourceParser.register_parser_type(:puppet, PuppetStrings::Yard::Parsers::Puppet::Parser, ['pp']) + YARD::Parser::SourceParser.register_parser_type(:json, PuppetStrings::Yard::Parsers::JSON::Parser, ['json']) # Register our handlers YARD::Handlers::Processor.register_handler_namespace(:puppet, PuppetStrings::Yard::Handlers::Puppet) YARD::Handlers::Processor.register_handler_namespace(:puppet_ruby, PuppetStrings::Yard::Handlers::Ruby) + YARD::Handlers::Processor.register_handler_namespace(:json, PuppetStrings::Yard::Handlers::JSON) # Register the tag directives PuppetStrings::Yard::Tags::ParameterDirective.register! @@ -46,7 +48,8 @@ def all_objects :puppet_defined_type, :puppet_type, :puppet_provider, - :puppet_function + :puppet_function, + :puppet_task ) end end @@ -75,6 +78,10 @@ def stats_for_puppet_functions output 'Puppet Functions', *type_statistics_all(:puppet_function) end + def stats_for_puppet_tasks + output 'Puppet Tasks', *type_statistics_all(:puppet_task) + end + def output(name, data, undoc = nil) # Monkey patch output to accommodate our larger header widths @total += data if data.is_a?(Integer) && undoc diff --git a/lib/puppet-strings/yard/code_objects.rb b/lib/puppet-strings/yard/code_objects.rb index 076eb9025..70f511a27 100644 --- a/lib/puppet-strings/yard/code_objects.rb +++ b/lib/puppet-strings/yard/code_objects.rb @@ -5,4 +5,5 @@ module PuppetStrings::Yard::CodeObjects require 'puppet-strings/yard/code_objects/type' require 'puppet-strings/yard/code_objects/provider' require 'puppet-strings/yard/code_objects/function' + require 'puppet-strings/yard/code_objects/task' end diff --git a/lib/puppet-strings/yard/code_objects/task.rb b/lib/puppet-strings/yard/code_objects/task.rb new file mode 100644 index 000000000..bf3a40e6b --- /dev/null +++ b/lib/puppet-strings/yard/code_objects/task.rb @@ -0,0 +1,70 @@ +require 'puppet-strings/yard/code_objects/group' + +# Implements the group for Puppet tasks. +class PuppetStrings::Yard::CodeObjects::Tasks < PuppetStrings::Yard::CodeObjects::Group + # Gets the singleton instance of the group. + # @return Returns the singleton instance of the group. + def self.instance + super(:puppet_tasks) + end + + # Gets the display name of the group. + # @param [Boolean] prefix whether to show a prefix. + # @return [String] Returns the display name of the group. + def name(prefix = false) + 'Puppet Tasks' + end +end + +# Implements the Puppet task code object. +class PuppetStrings::Yard::CodeObjects::Task < PuppetStrings::Yard::CodeObjects::Base + attr_reader :statement + + # Initializes a JSON task code object. + # @param statement TaskStatement object + # @return [void] + def initialize(statement) + @name = statement.name + @statement = statement + super(PuppetStrings::Yard::CodeObjects::Tasks.instance, name) + end + + # Gets the type of the code object. + # @return Returns the type of the code object. + def type + :puppet_task + end + + # Gets the source of the code object. + # @return Returns the source of the code object. + def source + @statement.source + end + + def parameters + parameters = [] + statement.json['parameters'].each do |name,props| + parameters.push({ name: name.to_s, + tag_name: 'param', + text: props['description'] || "", + types: [props['type']] || "" }) + end + parameters + end + + # Converts the code object to a hash representation. + # @return [Hash] Returns a hash representation of the code object. + def to_hash + { name: name.to_s, + file: statement.file, + line: statement.line, + docstring: { + text: statement.docstring, + tags: parameters + }, + source: statement.source, + supports_noop: statement.json['supports_noop'] || false, + input_method: statement.json['input_method'] + } + end +end diff --git a/lib/puppet-strings/yard/handlers.rb b/lib/puppet-strings/yard/handlers.rb index af7aaa2b2..7471a28ea 100644 --- a/lib/puppet-strings/yard/handlers.rb +++ b/lib/puppet-strings/yard/handlers.rb @@ -8,6 +8,11 @@ module Ruby require 'puppet-strings/yard/handlers/ruby/function_handler' end + # The module for custom JSON YARD handlers. + module JSON + require 'puppet-strings/yard/handlers/json/task_handler' + end + # The module for custom Puppet YARD handlers. module Puppet require 'puppet-strings/yard/handlers/puppet/class_handler' diff --git a/lib/puppet-strings/yard/handlers/json/base.rb b/lib/puppet-strings/yard/handlers/json/base.rb new file mode 100644 index 000000000..ff8151e3f --- /dev/null +++ b/lib/puppet-strings/yard/handlers/json/base.rb @@ -0,0 +1,5 @@ +class PuppetStrings::Yard::Handlers::JSON::Base < YARD::Handlers::Base + def self.handles?(statement) + handlers.any? {|handler| statement.is_a?(handler)} + end +end diff --git a/lib/puppet-strings/yard/handlers/json/task_handler.rb b/lib/puppet-strings/yard/handlers/json/task_handler.rb new file mode 100644 index 000000000..f0b081480 --- /dev/null +++ b/lib/puppet-strings/yard/handlers/json/task_handler.rb @@ -0,0 +1,31 @@ +require 'puppet-strings/yard/handlers/json/base' +require 'puppet-strings/yard/parsers' +require 'puppet-strings/yard/parsers/json/parser' + +class PuppetStrings::Yard::Handlers::JSON::TaskHandler < PuppetStrings::Yard::Handlers::JSON::Base + handles PuppetStrings::Yard::Parsers::JSON::TaskStatement + namespace_only + + process do + object = PuppetStrings::Yard::CodeObjects::Task.new(statement) + register object + + @kind = "Puppet Task #{object.name}." + @statement = statement + + validate_description + validate_params + end + + def validate_description + log.warn "Missing a description for #{@kind}." if @statement.docstring.empty? + end + + def validate_params + unless @statement.parameters.empty? + @statement.parameters.each do |param, val| + log.warn "Missing description for param '#{param}' in #{@kind}" if val['description'].nil? + end + end + end +end diff --git a/lib/puppet-strings/yard/parsers.rb b/lib/puppet-strings/yard/parsers.rb index 6916feefc..6353f0240 100644 --- a/lib/puppet-strings/yard/parsers.rb +++ b/lib/puppet-strings/yard/parsers.rb @@ -1,5 +1,9 @@ # The module for custom YARD parsers. module PuppetStrings::Yard::Parsers + # The module for custom YARD parsers for JSON. + module JSON + require 'puppet-strings/yard/parsers/json/parser' + end # The module for custom YARD parsers for the Puppet language. module Puppet require 'puppet-strings/yard/parsers/puppet/parser' diff --git a/lib/puppet-strings/yard/parsers/json/parser.rb b/lib/puppet-strings/yard/parsers/json/parser.rb new file mode 100644 index 000000000..a6f0c1321 --- /dev/null +++ b/lib/puppet-strings/yard/parsers/json/parser.rb @@ -0,0 +1,33 @@ +require 'puppet-strings/yard/parsers/json/task_statement' + +class PuppetStrings::Yard::Parsers::JSON::Parser < YARD::Parser::Base + attr_reader :file, :source + + # Initializes the parser. + # @param [String] source The source being parsed. + # @param [String] filename The file name of the file being parsed. + # @return [void] + def initialize(source, filename) + @file = filename + @source = source + @statements = [] + end + + def enumerator + @statements + end + + # Parses the source + # @return [void] + def parse + begin + json = JSON.parse(source) + @statements.push(PuppetStrings::Yard::Parsers::JSON::TaskStatement.new(json, @source, @file)) + rescue + log.error "Failed to parse #{@file}: " + @statements = [] + end + @statements.freeze + self + end +end diff --git a/lib/puppet-strings/yard/parsers/json/task_statement.rb b/lib/puppet-strings/yard/parsers/json/task_statement.rb new file mode 100644 index 000000000..5445e8591 --- /dev/null +++ b/lib/puppet-strings/yard/parsers/json/task_statement.rb @@ -0,0 +1,35 @@ +module PuppetStrings::Yard::Parsers::JSON + # Represents the Puppet Task statement. + class TaskStatement + attr_reader :line, :comments, :comments_range, :json, :file, :source, :docstring + + def initialize(json, source, file) + @file = file + @source = source + @json = json + @line = 0 + @comments_range = nil + @docstring = YARD::Docstring.new(@json['description']) + end + + def parameters + json['parameters'] || {} + end + + def comments_hash_flag + false + end + + def show + "" + end + + def comments + docstring.all + end + + def name + File.basename(@file).gsub('.json','') || "" + end + end +end diff --git a/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_task.erb b/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_task.erb new file mode 100644 index 000000000..095188f56 --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_task.erb @@ -0,0 +1,9 @@ +<% even = false %> +<% @items.each do |item| %> +
  • +
    + <%= linkify item, h(item.name(true)) %> +
    +
  • + <% even = !even %> +<% end %> diff --git a/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb b/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb index a71e11779..e178613e5 100644 --- a/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb +++ b/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb @@ -62,3 +62,12 @@ def generate_class_list @list_type = 'class' generate_list_contents end + +# Generates the searchable Puppet Task list. +# @return [void] +def generate_puppet_task_list + @items = Registry.all(:puppet_task).sort_by {|t| t.name.to_s } + @list_title = 'Puppet Task List' + @list_type = 'puppet_task' + generate_list_contents +end diff --git a/lib/puppet-strings/yard/templates/default/layout/html/setup.rb b/lib/puppet-strings/yard/templates/default/layout/html/setup.rb index 703d2f5e0..d228a3661 100644 --- a/lib/puppet-strings/yard/templates/default/layout/html/setup.rb +++ b/lib/puppet-strings/yard/templates/default/layout/html/setup.rb @@ -4,7 +4,7 @@ def init case object when '_index.html' @page_title = options.title - sections :layout, [:index, [:listing, [:classes, :defined_types, :types, :providers, :functions, :files, :objects]]] + sections :layout, [:index, [:listing, [:classes, :defined_types, :types, :providers, :functions, :tasks, :files, :objects]]] else super end @@ -46,6 +46,10 @@ def layout @nav_url = url_for_list('puppet_function') @page_title = "Puppet Function: #{object.name} (#{object.function_type})" @path = object.path + when PuppetStrings::Yard::CodeObjects::Task + @nav_url = url_for_list('puppet_task') + @page_title = "Puppet Task: #{object.name}" + @path = object.path else @path = object.path end @@ -82,6 +86,11 @@ def create_menu_lists title: 'Puppet Functions', search_title: 'Puppet Functions' }, + { + type: 'puppet_task', + title: 'Puppet Tasks', + search_totle: 'Puppet Tasks' + }, { type: 'class', title: 'Ruby Classes', @@ -163,6 +172,14 @@ def functions erb(:objects) end +# Renders the tasks section. +# @return [String] Returns the rendered section. +def tasks + @title = 'Puppet Task Listing A-Z' + @objects_by_letter = objects_by_letter(:puppet_task) + erb(:objects) +end + # Renders the objects section. # @return [String] Returns the rendered section. def objects diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/box_info.erb b/lib/puppet-strings/yard/templates/default/puppet_task/html/box_info.erb new file mode 100644 index 000000000..938caf571 --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/box_info.erb @@ -0,0 +1,9 @@ +
    +
    +
    Defined in:
    +
    + <%= object.file %>,
    + <%= object.file.gsub('json','rb') %>
    + + + diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/header.erb b/lib/puppet-strings/yard/templates/default/puppet_task/html/header.erb new file mode 100644 index 000000000..49a2639ce --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/header.erb @@ -0,0 +1 @@ +

    Puppet Task: <%= object.name %>

    diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/input.erb b/lib/puppet-strings/yard/templates/default/puppet_task/html/input.erb new file mode 100644 index 000000000..d1c9930e0 --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/input.erb @@ -0,0 +1,5 @@ +<% if json['input_method'] || json['supports_noop'] %> +
    +

    Supports noop? <%= json['supports_noop'] ? "true" : "false" %>

    +
    +<% end %> diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/overview.erb b/lib/puppet-strings/yard/templates/default/puppet_task/html/overview.erb new file mode 100644 index 000000000..3fc7782b1 --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/overview.erb @@ -0,0 +1,6 @@ +

    Overview

    +
    +
    + <%= description %> +
    +
    diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/parameters.erb b/lib/puppet-strings/yard/templates/default/puppet_task/html/parameters.erb new file mode 100644 index 000000000..6c94e4bed --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/parameters.erb @@ -0,0 +1,16 @@ +<% if @parameters && !@parameters.empty? %> +
    +

    <%= @tag_title %>

    + +
    +<% end %> diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/setup.rb b/lib/puppet-strings/yard/templates/default/puppet_task/html/setup.rb new file mode 100644 index 000000000..27820f88f --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/setup.rb @@ -0,0 +1,22 @@ +# Initializes the template. +# @return [void] +def init + sections :header, :box_info, T('tags'), :overview, :input, :parameters +end + +def json + object.statement.json +end + +def description + json['description'] +end + +# Renders the parameters section. +# @return [String] Returns the rendered section. +def parameters + @parameters = json['parameters'] || [] + @parameters.to_a.sort! + @tag_title = 'Parameters' + erb(:parameters) +end diff --git a/lib/puppet-strings/yard/templates/default/puppet_task/html/supports_noop.erb b/lib/puppet-strings/yard/templates/default/puppet_task/html/supports_noop.erb new file mode 100644 index 000000000..bf7bff246 --- /dev/null +++ b/lib/puppet-strings/yard/templates/default/puppet_task/html/supports_noop.erb @@ -0,0 +1,3 @@ +<% if json['supports_noop'] %> +Supports noop? <%= json['supports_noop'] %> +<% end %> diff --git a/lib/puppet-strings/yard/templates/default/tags/setup.rb b/lib/puppet-strings/yard/templates/default/tags/setup.rb index 888d05a12..99a37774c 100644 --- a/lib/puppet-strings/yard/templates/default/tags/setup.rb +++ b/lib/puppet-strings/yard/templates/default/tags/setup.rb @@ -5,7 +5,8 @@ def param object.type == :method || object.type == :puppet_class || object.type == :puppet_defined_type || - object.type == :puppet_function + object.type == :puppet_function || + object.type == :puppet_task end # Renders the overload section. diff --git a/spec/fixtures/unit/json/output.json b/spec/fixtures/unit/json/output.json index c65bb656c..73815d8b0 100644 --- a/spec/fixtures/unit/json/output.json +++ b/spec/fixtures/unit/json/output.json @@ -598,5 +598,52 @@ }, "source": "Puppet::Functions.create_function(:func4x_1) do\n # @param param1 The first parameter.\n # @return [Undef] Returns nothing.\n dispatch :foobarbaz do\n param 'Integer', :param1\n end\nend" } + ], + "puppet_tasks": [ + { + "name": "(stdin)", + "file": "(stdin)", + "line": 0, + "docstring": { + "text": "Allows you to backup your database to local file.", + "tags": [ + { + "name": "database", + "tag_name": "param", + "text": "Database to connect to", + "types": [ + "Optional[String[1]]" + ] + }, + { + "name": "user", + "tag_name": "param", + "text": "The user", + "types": [ + "Optional[String[1]]" + ] + }, + { + "name": "password", + "tag_name": "param", + "text": "The password", + "types": [ + "Optional[String[1]]" + ] + }, + { + "name": "sql", + "tag_name": "param", + "text": "Path to file you want backup to", + "types": [ + "String[1]" + ] + } + ] + }, + "source": "{\n \"description\": \"Allows you to backup your database to local file.\",\n \"input_method\": \"stdin\",\n \"parameters\": {\n \"database\": {\n \"description\": \"Database to connect to\",\n \"type\": \"Optional[String[1]]\"\n },\n \"user\": {\n \"description\": \"The user\",\n \"type\": \"Optional[String[1]]\"\n },\n \"password\": {\n \"description\": \"The password\",\n \"type\": \"Optional[String[1]]\"\n },\n \"sql\": {\n \"description\": \"Path to file you want backup to\",\n \"type\": \"String[1]\"\n }\n }\n}\n", + "supports_noop": false, + "input_method": "stdin" + } ] } diff --git a/spec/fixtures/unit/markdown/output.md b/spec/fixtures/unit/markdown/output.md index 9d225c872..51a160d16 100644 --- a/spec/fixtures/unit/markdown/output.md +++ b/spec/fixtures/unit/markdown/output.md @@ -15,6 +15,8 @@ * [`func3x`](#func3x): Documentation for an example 3.x function. * [`func4x`](#func4x): An example 4.x function. * [`func4x_1`](#func4x_1): An example 4.x function with only one signature. +## Tasks +* [`(stdin)`](#(stdin)): Allows you to backup your database to local file. ## Classes ### klass @@ -381,3 +383,37 @@ Data type: `Integer` The first parameter. +## Tasks + +### (stdin) + +Allows you to backup your database to local file. + +**Supports noop?** false + +#### Parameters + +##### `database` + +Data type: `Optional[String[1]]` + +Database to connect to + +##### `user` + +Data type: `Optional[String[1]]` + +The user + +##### `password` + +Data type: `Optional[String[1]]` + +The password + +##### `sql` + +Data type: `String[1]` + +Path to file you want backup to + diff --git a/spec/unit/puppet-strings/json_spec.rb b/spec/unit/puppet-strings/json_spec.rb index c81adf803..713fb14ee 100644 --- a/spec/unit/puppet-strings/json_spec.rb +++ b/spec/unit/puppet-strings/json_spec.rb @@ -30,6 +30,31 @@ class klass(Integer $param1, $param2, String $param3 = hi) inherits foo::bar { # @return [Undef] Returns nothing. function func(Integer $param1, $param2, String $param3 = hi) { } +SOURCE + + YARD::Parser::SourceParser.parse_string(<<-SOURCE, :json) +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin", + "parameters": { + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + }, + "user": { + "description": "The user", + "type": "Optional[String[1]]" + }, + "password": { + "description": "The password", + "type": "Optional[String[1]]" + }, + "sql": { + "description": "Path to file you want backup to", + "type": "String[1]" + } + } +} SOURCE YARD::Parser::SourceParser.parse_string(<<-SOURCE, :ruby) diff --git a/spec/unit/puppet-strings/markdown_spec.rb b/spec/unit/puppet-strings/markdown_spec.rb index 8c0c052bc..52264e582 100644 --- a/spec/unit/puppet-strings/markdown_spec.rb +++ b/spec/unit/puppet-strings/markdown_spec.rb @@ -63,6 +63,55 @@ class noparams () {} Boolean $param4 = true ) { } +SOURCE + YARD::Parser::SourceParser.parse_string(<<-SOURCE, :json) +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin", + "parameters": { + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + }, + "user": { + "description": "The user", + "type": "Optional[String[1]]" + }, + "password": { + "description": "The password", + "type": "Optional[String[1]]" + }, + "sql": { + "description": "Path to file you want backup to", + "type": "String[1]" + } + } +} +SOURCE + + YARD::Parser::SourceParser.parse_string(<<-SOURCE, :json) +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin", + "parameters": { + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + }, + "user": { + "description": "The user", + "type": "Optional[String[1]]" + }, + "password": { + "description": "The password", + "type": "Optional[String[1]]" + }, + "sql": { + "description": "Path to file you want backup to", + "type": "String[1]" + } + } +} SOURCE YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet) diff --git a/spec/unit/puppet-strings/yard/code_objects/task_spec.rb b/spec/unit/puppet-strings/yard/code_objects/task_spec.rb new file mode 100644 index 000000000..ea72cf157 --- /dev/null +++ b/spec/unit/puppet-strings/yard/code_objects/task_spec.rb @@ -0,0 +1,92 @@ +require 'spec_helper' +require 'puppet-strings/yard/code_objects/task' +require 'puppet-strings/yard/parsers/json/task_statement' + +describe PuppetStrings::Yard::CodeObjects::Task do + let(:source) { <<-SOURCE +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin", + "parameters": { + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + }, + "user": { + "description": "The user", + "type": "Optional[String[1]]" + }, + "password": { + "description": "The password", + "type": "Optional[String[1]]" + }, + "sql": { + "description": "Path to file you want backup to", + "type": "String[1]" + } + } +} +SOURCE + } + let(:json) { JSON.parse(source) } + let(:statement) { PuppetStrings::Yard::Parsers::JSON::TaskStatement.new(json, source, "test.json") } + subject { PuppetStrings::Yard::CodeObjects::Task.new(statement) } + + describe '#type' do + it 'returns the correct type' do + expect(subject.type).to eq(:puppet_task) + end + end + + describe '#source' do + it 'returns the source' do + expect(subject.source).to eq(source) + end + end + + describe '#to_hash' do + let(:expected) do + { + :name => "test", + :supports_noop => false, + :docstring => { + :text=>"Allows you to backup your database to local file.", + :tags=> [ + { + :name=>"database", + :tag_name=>"param", + :text=>"Database to connect to", + :types=> ["Optional[String[1]]"] + }, + { + :name=>"user", + :tag_name=>"param", + :text=>"The user", + :types=> ["Optional[String[1]]"] + }, + { + :name=>"password", + :tag_name=>"param", + :text=>"The password", + :types=> ["Optional[String[1]]"] + }, + { + :name=>"sql", + :tag_name=>"param", + :text=>"Path to file you want backup to", + :types=>["String[1]"] + } + ] + }, + :file => "test.json", + :input_method => "stdin", + :line => 0, + :source => "{\n \"description\": \"Allows you to backup your database to local file.\",\n \"input_method\": \"stdin\",\n \"parameters\": {\n \"database\": {\n \"description\": \"Database to connect to\",\n \"type\": \"Optional[String[1]]\"\n },\n \"user\": {\n \"description\": \"The user\",\n \"type\": \"Optional[String[1]]\"\n },\n \"password\": {\n \"description\": \"The password\",\n \"type\": \"Optional[String[1]]\"\n },\n \"sql\": {\n \"description\": \"Path to file you want backup to\",\n \"type\": \"String[1]\"\n }\n }\n}\n" + } + end + + it 'returns the correct hash' do + expect(subject.to_hash).to eq(expected) + end + end +end diff --git a/spec/unit/puppet-strings/yard/handlers/json/task_handler_spec.rb b/spec/unit/puppet-strings/yard/handlers/json/task_handler_spec.rb new file mode 100644 index 000000000..1e557204e --- /dev/null +++ b/spec/unit/puppet-strings/yard/handlers/json/task_handler_spec.rb @@ -0,0 +1,124 @@ +require 'spec_helper' +require 'puppet-strings/yard' + +describe PuppetStrings::Yard::Handlers::JSON::TaskHandler do + subject { + YARD::Parser::SourceParser.parse_string(source, :json) + YARD::Registry.all(:puppet_task) + } + + describe 'parsing source without a task definition' do + let(:source) { 'notice hi' } + + it 'no defined types should be in the registry' do + expect(subject.empty?).to eq(true) + end + end + + describe 'parsing source with a syntax error' do + let(:source) { <<-SOURCE +{ + "input_method": "stdin", + "parameters": + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + } + } +} +SOURCE + } + + it 'should log an error' do + expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\):/).to_stdout_from_any_process + expect(subject.empty?).to eq(true) + end + end + + describe 'parsing a defined type with a missing docstring' do + let(:source) { <<-SOURCE +{ + "input_method": "stdin", + "parameters": { + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + }, + "user": { + "description": "The user", + "type": "Optional[String[1]]" + }, + "password": { + "description": "The password", + "type": "Optional[String[1]]" + }, + "sql": { + "description": "Path to file you want backup to", + "type": "String[1]" + } + } +} +SOURCE + } + + it 'should log a warning' do + expect{ subject }.to output(/\[warn\]: Missing a description for Puppet Task \(stdin\)/).to_stdout_from_any_process + end + end + + describe 'parsing a defined type with a docstring' do + let(:source) { <<-SOURCE +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin", + "parameters": { + "database": { + "description": "Database to connect to", + "type": "Optional[String[1]]" + }, + "user": { + "description": "The user", + "type": "Optional[String[1]]" + }, + "password": { + "description": "The password", + "type": "Optional[String[1]]" + }, + "sql": { + "description": "Path to file you want backup to", + "type": "String[1]" + } + } +} + +SOURCE + } + + it 'should register a task object' do + expect(subject.size).to eq(1) + object = subject.first + expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Task) + expect(object.namespace).to eq(PuppetStrings::Yard::CodeObjects::Tasks.instance) + end + end + + describe 'parsing a Task with a missing parameter description' do + let(:source) { <<-SOURCE +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin", + "parameters": { + "database": { + "type": "Optional[String[1]]" + } + } +} +SOURCE + } + + it 'should output a warning' do + expect{ subject }.to output(/\[warn\]: Missing description for param 'database' in Puppet Task \(stdin\)/).to_stdout_from_any_process + end + end + +end diff --git a/spec/unit/puppet-strings/yard/parsers/json/parser_spec.rb b/spec/unit/puppet-strings/yard/parsers/json/parser_spec.rb new file mode 100644 index 000000000..1fbbbf35e --- /dev/null +++ b/spec/unit/puppet-strings/yard/parsers/json/parser_spec.rb @@ -0,0 +1,70 @@ +require 'spec_helper' +require 'puppet-strings/yard' + +describe PuppetStrings::Yard::Parsers::JSON::Parser do + subject { PuppetStrings::Yard::Parsers::JSON::Parser.new(source, file) } + let(:file) { 'test.json' } + + describe 'initialization of the parser' do + let(:source) { 'notice hi' } + + it 'should store the original source' do + expect(subject.source).to eq(source) + end + + it 'should store the original file name' do + expect(subject.file).to eq(file) + end + + it 'should have no relevant statements' do + subject.parse + expect(subject.enumerator.empty?).to be_truthy + end + end + + describe 'parsing invalid JSON' do + let(:source) { < 0).to be true + end + end + context 'no params' do + let(:source) { <<-SOURCE +{ + "description": "Allows you to backup your database to local file.", + "input_method": "stdin" +} +SOURCE + } + it 'returns an empty hash' do + expect(subject.parameters).to eq({}) + end + end + end + +end