pe-razor-client 0.15.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +27 -0
  3. data/bin/razor +27 -2
  4. data/lib/razor/cli.rb +11 -2
  5. data/lib/razor/cli/command.rb +150 -0
  6. data/lib/razor/cli/document.rb +8 -4
  7. data/lib/razor/cli/format.rb +46 -22
  8. data/lib/razor/cli/navigate.rb +28 -156
  9. data/lib/razor/cli/parse.rb +49 -7
  10. data/lib/razor/cli/query.rb +69 -0
  11. data/lib/razor/cli/table_format.rb +41 -0
  12. data/lib/razor/cli/transforms.rb +25 -0
  13. data/lib/razor/cli/version.rb +1 -1
  14. data/lib/razor/cli/views.yaml +53 -2
  15. data/spec/cli/command_spec.rb +66 -0
  16. data/spec/cli/format_spec.rb +95 -5
  17. data/spec/cli/navigate_spec.rb +50 -6
  18. data/spec/cli/parse_spec.rb +42 -2
  19. data/spec/fixtures/vcr/Razor_CLI_Navigate/argument_formatting/should_allow_in_string.yml +233 -0
  20. data/spec/fixtures/vcr/Razor_CLI_Navigate/argument_formatting/should_allow_spaces.yml +281 -548
  21. data/spec/fixtures/vcr/Razor_CLI_Navigate/for_command_help/should_provide_command_help_for_razor_--help_command_.yml +160 -37
  22. data/spec/fixtures/vcr/Razor_CLI_Navigate/for_command_help/should_provide_command_help_for_razor_-h_command_.yml +160 -37
  23. data/spec/fixtures/vcr/Razor_CLI_Navigate/for_command_help/should_provide_command_help_for_razor_command_--help_.yml +160 -37
  24. data/spec/fixtures/vcr/Razor_CLI_Navigate/for_command_help/should_provide_command_help_for_razor_command_-h_.yml +160 -37
  25. data/spec/fixtures/vcr/Razor_CLI_Navigate/for_command_help/should_provide_command_help_for_razor_command_help_.yml +160 -37
  26. data/spec/fixtures/vcr/Razor_CLI_Navigate/for_command_help/should_provide_command_help_for_razor_help_command_.yml +160 -37
  27. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_authentication/should_preserve_that_across_navigation.yml +10 -10
  28. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_authentication/should_supply_that_to_the_API_service.yml +5 -5
  29. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_invalid_parameter/should_fail_with_bad_JSON.yml +71 -166
  30. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_invalid_parameter/should_fail_with_malformed_argument.yml +109 -59
  31. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_array/should_merge_an_array_into_an_existing_array.yml +527 -1360
  32. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_array/should_merge_the_arguments_as_an_array.yml +528 -1361
  33. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_array/should_merge_the_arguments_into_an_existing_array.yml +528 -1361
  34. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_object/should_construct_a_json_object.yml +80 -111
  35. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_object/should_construct_a_json_object_with_unicode.yml +137 -123
  36. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_object/should_fail_with_mixed_types_array_then_hash_.yml +71 -166
  37. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_multiple_arguments_with_same_name/combining_as_an_object/should_fail_with_mixed_types_hash_then_array_.yml +71 -102
  38. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_no_parameters/should_fail_with_bad_JSON.yml +98 -5
  39. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_query_parameters/should_append_limit.yml +69 -0
  40. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_query_parameters/should_append_start.yml +69 -0
  41. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_query_parameters/should_not_fail_when_query_returns_details_for_one_item.yml +313 -0
  42. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_query_parameters/should_store_query_without_query_parameters.yml +557 -0
  43. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_query_parameters/should_throw_an_error_if_the_query_parameter_is_not_in_the_API.yml +36 -0
  44. data/spec/fixtures/vcr/Razor_CLI_Navigate/with_query_parameters/should_throw_an_error_if_the_query_parameter_is_not_in_the_API_from_a_single_item.yml +280 -0
  45. data/spec/fixtures/vcr/Razor_CLI_Parse/_new/_help/should_print_a_list_of_known_endpoints.yml +5 -5
  46. data/spec/spec_helper.rb +8 -4
  47. metadata +26 -7
@@ -6,7 +6,7 @@ module Razor::CLI
6
6
 
7
7
  class Parse
8
8
  extend Forwardable
9
- DEFAULT_RAZOR_API = "http://localhost:8080/api"
9
+ DEFAULT_RAZOR_API = "https://localhost:8151/api"
10
10
 
11
11
  def_delegator 'navigate', 'query?'
12
12
 
@@ -18,12 +18,12 @@ module Razor::CLI
18
18
  @dump = true
19
19
  end
20
20
 
21
- opts.on "-f", "--full", "Show full details when viewing entities" do
22
- @format = 'full'
21
+ opts.on "-a", "--api", "Show API help for a command" do
22
+ @api_help = true
23
23
  end
24
24
 
25
- opts.on "-s", "--short", "Show shortened details when viewing entities" do
26
- @format = 'short'
25
+ opts.on "-k", "--insecure", "Allow SSL connections without verified certificates" do
26
+ @verify_ssl = false
27
27
  end
28
28
 
29
29
  opts.on "-u", "--url URL",
@@ -53,14 +53,28 @@ module Razor::CLI
53
53
  end
54
54
 
55
55
  def version
56
+ begin
56
57
  <<-VERSION
57
58
  Razor Server version: #{navigate.server_version}
58
59
  Razor Client version: #{Razor::CLI::VERSION}
59
60
  VERSION
61
+ rescue RestClient::Unauthorized
62
+ puts <<-UNAUTH
63
+ Error: Credentials are required to connect to the server at #{@api_url}"
64
+ UNAUTH
65
+ exit 1
66
+ rescue
67
+ puts <<-ERR
68
+ Error: Could not connect to the server at #{@api_url}. More help is available after pointing
69
+ the client to a Razor server
70
+ ERR
71
+ exit 1
72
+ end
60
73
  end
61
74
 
62
75
  def help
63
76
  output = get_optparse.to_s
77
+ exit = 0
64
78
  begin
65
79
  output << <<-HELP
66
80
  #{list_things("Collections", navigate.collections)}
@@ -80,19 +94,25 @@ HELP
80
94
  output << <<-UNAUTH
81
95
  Error: Credentials are required to connect to the server at #{@api_url}"
82
96
  UNAUTH
97
+ exit = 1
83
98
  rescue
84
99
  output << <<-ERR
85
100
  Error: Could not connect to the server at #{@api_url}. More help is available after pointing
86
101
  the client to a Razor server
87
102
  ERR
103
+ exit = 1
88
104
  end
89
- output
105
+ [output, exit]
90
106
  end
91
107
 
92
108
  def show_version?
93
109
  !!@show_version
94
110
  end
95
111
 
112
+ def show_api_help?
113
+ !!@api_help
114
+ end
115
+
96
116
  def show_help?
97
117
  !!@option_help
98
118
  end
@@ -105,13 +125,32 @@ ERR
105
125
  !!@dump
106
126
  end
107
127
 
108
- attr_reader :api_url, :format, :args
128
+ def verify_ssl?
129
+ !!@verify_ssl
130
+ end
131
+
132
+ attr_reader :api_url, :args
133
+ # The format can be determined from later segments.
134
+ attr_accessor :format, :stripped_args, :ssl_ca_file
109
135
 
110
136
  def initialize(args)
111
137
  parse_and_set_api_url(ENV["RAZOR_API"] || DEFAULT_RAZOR_API, :env)
112
138
  @args = args.dup
139
+ # To be populated externally.
140
+ @stripped_args = []
113
141
  @format = 'short'
142
+ # If this is set, it should actually exist.
143
+ if ENV['RAZOR_CA_FILE'] && !File.exists?(ENV['RAZOR_CA_FILE'])
144
+ raise Razor::CLI::InvalidCAFileError.new(ENV['RAZOR_CA_FILE'])
145
+ end
146
+ ca_file = ENV["RAZOR_CA_FILE"] || '/etc/puppetlabs/puppet/ssl/certs/ca.pem'
147
+ @ssl_ca_file = ca_file if ca_file && File.exists?(ca_file)
114
148
  @args = get_optparse.order(@args)
149
+
150
+ # Localhost won't match the server's certificate; no verification required.
151
+ # This needs to happen after get_optparse so `-k` and `-u` can take effect.
152
+ @verify_ssl ||= (@api_url.hostname != 'localhost')
153
+
115
154
  @args = set_help_vars(@args)
116
155
  if @args == ['version'] or @show_version
117
156
  @show_version = true
@@ -150,6 +189,9 @@ ERR
150
189
  private
151
190
  def parse_and_set_api_url(url, source)
152
191
  begin
192
+ unless url.start_with?('http:') or url.start_with?('https:')
193
+ raise Razor::CLI::InvalidURIError.new(url, source)
194
+ end
153
195
  @api_url = URI.parse(url)
154
196
  rescue URI::InvalidURIError => e
155
197
  raise Razor::CLI::InvalidURIError.new(url, source)
@@ -0,0 +1,69 @@
1
+ class Razor::CLI::Query
2
+ def initialize(parse, navigate, collections, segments)
3
+ @parse = parse
4
+ @navigate = navigate
5
+ @collections = collections
6
+ @segments = segments
7
+ @stripped_segments = []
8
+ @options = {}
9
+ end
10
+
11
+ def stripped_segments
12
+ @stripped_segments.join
13
+ end
14
+
15
+ def get_optparse(doc, nav)
16
+ # If the last document is an Array, we need to find
17
+ # which element matches the given query. Once found,
18
+ # return the 'params' section, if it has one.
19
+ if doc.is_a?(Array)
20
+ query = doc.find {|coll| coll['name'] == nav}
21
+ params = (query && query['params']) || {}
22
+ elsif doc.is_a?(Hash)
23
+ params = (doc[nav].is_a?(Hash) && doc[nav].has_key?('params') &&
24
+ doc[nav]['params'].is_a?(Hash) && doc[nav]['params']) || {}
25
+ end
26
+ @queryoptparse = OptionParser.new do |opts|
27
+ opts.on "-f", "--full", "Show full details when viewing entities" do
28
+ @parse.format = 'full'
29
+ end
30
+
31
+ opts.on "-s", "--short", "Show shortened details when viewing entities" do
32
+ @parse.format = 'short'
33
+ end
34
+
35
+ params.each do |param, args|
36
+ if args['type'] == 'boolean'
37
+ opts.on "--#{param}" do
38
+ @options[param] = true
39
+ end
40
+ else
41
+ opts.on "--#{param} VALUE" do |value|
42
+ @options[param] = value
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ def run
50
+ @doc = @collections
51
+ while @segments.any?
52
+ nav = @segments.shift
53
+ @parse.stripped_args << nav
54
+ @segments = get_optparse(@doc, nav).order(@segments)
55
+ @doc = @navigate.move_to nav, @doc, @options
56
+ end
57
+
58
+ # Get the next level if it's a list of objects.
59
+ if @doc.is_a?(Hash) and @doc['items'].is_a?(Array)
60
+ # Cache doc_resource since these queries are just for extra detail.
61
+ temp_doc_resource = @navigate.doc_resource
62
+ @doc['items'] = @doc['items'].map do |item|
63
+ item.is_a?(Hash) && item.has_key?('id') ? @navigate.json_get(URI.parse(item['id'])) : item
64
+ end
65
+ @navigate.doc_resource = temp_doc_resource
66
+ end
67
+ @doc
68
+ end
69
+ end
@@ -0,0 +1,41 @@
1
+ require 'command_line_reporter'
2
+ class Razor::CLI::TableFormat
3
+ include CommandLineReporter
4
+
5
+ def run(doc, column_overrides)
6
+ suppress_output
7
+ table(:border => true, :encoding => :ascii) do
8
+ headings = (column_overrides or get_headers(doc))
9
+ row do
10
+ headings.each do |header|
11
+ column(header, :width => get_width(header, doc))
12
+ end
13
+ end
14
+ doc.each do |page|
15
+ row do
16
+ headings.each do |heading|
17
+ column(page[heading])
18
+ end
19
+ end
20
+ end
21
+ end
22
+ # Capturing stores the string, rather than printing to STDOUT (default).
23
+ capture_output.strip
24
+ end
25
+
26
+ def get_width(header, doc)
27
+ (doc.map do |page|
28
+ (page[header] or '').to_s.length
29
+ end << header.to_s.length).max
30
+ end
31
+
32
+ def get_headers(doc)
33
+ [].tap do |headers|
34
+ doc.map do |page|
35
+ page.map do |item|
36
+ headers << item[0] unless headers.include?(item[0])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -26,9 +26,20 @@ module Razor::CLI
26
26
  def name(obj)
27
27
  obj ? obj['name'] : "---"
28
28
  end
29
+ def name_hide_nil(obj)
30
+ raise Razor::CLI::HideColumnError if obj.nil?
31
+ obj['name']
32
+ end
29
33
  def name_if_present(obj)
30
34
  obj ? obj['name'] : "---"
31
35
  end
36
+ def name_or_whole(obj)
37
+ if obj
38
+ (obj['name'] ? obj['name'] : obj)
39
+ else
40
+ '---'
41
+ end
42
+ end
32
43
  def count_column(hash)
33
44
  hash['count']
34
45
  end
@@ -38,5 +49,19 @@ module Razor::CLI
38
49
  def count_hash(hash)
39
50
  hash.is_a?(Hash) ? hash.keys.size : 0
40
51
  end
52
+ def event_msg(obj)
53
+ raise Razor::CLI::HideColumnError if obj['msg'].nil?
54
+ obj['msg'].to_s[0..50] + (obj['msg'].to_s.size > 50 ? '...' : '')
55
+ end
56
+ def full_event_msg(obj)
57
+ raise Razor::CLI::HideColumnError if obj['msg'].nil?
58
+ obj['msg']
59
+ end
60
+ def event_entities(hash)
61
+ shallow_hash(Hash[hash].keep_if {|k,_| ['task', 'policy', 'broker', 'repo', 'node', 'command'].include?(k)})
62
+ end
63
+ def event_misc(hash)
64
+ shallow_hash(Hash[hash].delete_if {|k,_|['task', 'policy', 'broker', 'repo', 'node', 'msg', 'command'].include?(k)})
65
+ end
41
66
  end
42
67
  end
@@ -18,7 +18,7 @@ module Razor
18
18
  #
19
19
  # The next line is the one that our packaging tools modify, so please make
20
20
  # sure that any change to it is discussed and agreed first.
21
- version = '0.15.2.2'
21
+ version = '1.0.0'
22
22
 
23
23
  if version == "DEVELOPMENT"
24
24
  root = File.expand_path("../../..", File.dirname(__FILE__))
@@ -9,13 +9,14 @@
9
9
  # `+show`: This section configures which attributes are shown in the output.
10
10
  # `+layout`: This configures whether to use 'list' or 'table' output.
11
11
  # `+column`: This changes which column is used in the field formatting.
12
+ # `+format`: This references a method inside `transforms.rb` which will mutate the column's value.
12
13
  collections:
13
14
  brokers:
14
15
  +short:
15
16
  +layout: table
16
17
  +show:
17
18
  name:
18
- broker-type:
19
+ broker_type:
19
20
  configuration:
20
21
  +format: nested
21
22
  policies:
@@ -25,7 +26,7 @@ collections:
25
26
  +layout: list
26
27
  +show:
27
28
  name:
28
- broker-type:
29
+ broker_type:
29
30
  configuration:
30
31
  policies:
31
32
  +format: count_column
@@ -194,3 +195,53 @@ collections:
194
195
  +format: count
195
196
  status:
196
197
  submitted_at:
198
+ events:
199
+ +short:
200
+ +layout: table
201
+ +show:
202
+ name:
203
+ timestamp:
204
+ message:
205
+ +column: entry
206
+ +format: event_msg
207
+ entities:
208
+ +column: entry
209
+ +format: event_entities
210
+ entry:
211
+ +column: entry
212
+ +format: event_misc
213
+ member:
214
+ +short:
215
+ +show:
216
+ name:
217
+ timestamp:
218
+ message:
219
+ +column: entry
220
+ +format: full_event_msg
221
+ broker:
222
+ +format: name_hide_nil
223
+ node:
224
+ +format: name_hide_nil
225
+ policy:
226
+ +format: name_hide_nil
227
+ repo:
228
+ +format: name_hide_nil
229
+ command:
230
+ +format: name_or_whole
231
+ task:
232
+ +format: name_hide_nil
233
+ entry:
234
+ hooks:
235
+ +short:
236
+ +layout: table
237
+ +show:
238
+ name:
239
+ hook_type:
240
+ configuration:
241
+ +format: shallow_hash
242
+ member:
243
+ +short:
244
+ +show:
245
+ name:
246
+ hook_type:
247
+ configuration:
@@ -0,0 +1,66 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # Needed to make the client work on Ruby 1.8.7
3
+ unless Kernel.respond_to?(:require_relative)
4
+ module Kernel
5
+ def require_relative(path)
6
+ require File.join(File.dirname(caller[0]), path.to_str)
7
+ end
8
+ end
9
+ end
10
+
11
+ require_relative '../spec_helper'
12
+
13
+ describe Razor::CLI::Command do
14
+ Command = Razor::CLI::Command
15
+ # let(:inst) { Class.new { include Razor::CLI::Command } }
16
+
17
+ let :existing_value do nil end
18
+
19
+ context "convert_arg" do
20
+ it "performs no conversion for 'json' reserved argument name" do
21
+ value = '/some/path'
22
+ cmd_schema = {'json' => {'type' => 'number', 'aliases' => ['b']}}
23
+ result = Command.convert_arg('json', value, existing_value, cmd_schema)
24
+ result.should == '/some/path'
25
+ end
26
+
27
+ [['number', '123', 123], ['array', '[1, 2]', [1, 2]], ['array', '1', [1]],
28
+ ['object', '{"abc":123}', {'abc' => 123}], ['object', 'abc=123', {'abc' => '123'}]].
29
+ each do |type, orig, final|
30
+ it "finds the right datatype for #{type} #{orig}" do
31
+ cmd_schema = {"tags"=>{"type"=>"#{type}"}}
32
+ result = Command.convert_arg('tags', orig, existing_value, cmd_schema)
33
+ result.should == final
34
+ end
35
+ end
36
+ it "returns argument as-is when it cannot find the datatype" do
37
+ cmd_schema = {"tags"=>{}}
38
+ result = Command.convert_arg('tags', 'abc', existing_value, cmd_schema)
39
+ result.should == 'abc'
40
+ end
41
+ it "appends to existing values" do
42
+ cmd_schema = {"tags"=>{'type' => 'array'}}
43
+ existing_value = ['abc']
44
+ result = Command.convert_arg('tags', 'def', existing_value, cmd_schema)
45
+ result.should == %w(abc def)
46
+ end
47
+ end
48
+
49
+ context "resolve_alias" do
50
+ it "resolves the alias when alias is present" do
51
+ cmd_schema = {'def' => {'type' => 'array', 'aliases' => ['abc']}}
52
+ result = Command.resolve_alias('abc', cmd_schema)
53
+ result.should == 'def'
54
+ end
55
+ it "leaves name alone when alias is present" do
56
+ cmd_schema = {'def' => {'type' => 'array', 'aliases' => ['abc']}}
57
+ result = Command.resolve_alias('ghi', cmd_schema)
58
+ result.should == 'ghi'
59
+ end
60
+ it "leaves name alone when no alias is present" do
61
+ cmd_schema = {'def' => {'type' => 'array'}}
62
+ result = Command.resolve_alias('abc', cmd_schema)
63
+ result.should == 'abc'
64
+ end
65
+ end
66
+ end
@@ -1,3 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  # Needed to make the client work on Ruby 1.8.7
2
3
  unless Kernel.respond_to?(:require_relative)
3
4
  module Kernel
@@ -14,7 +15,8 @@ describe Razor::CLI::Format do
14
15
  include described_class
15
16
 
16
17
  def format(doc, args = {})
17
- args = {:format => 'short', :args => ['something', 'else'], :query? => true, :show_command_help? => false}.merge(args)
18
+ args = {:format => 'short', :stripped_args => ['something', 'else'], :query? => true, :show_command_help? => false,
19
+ :show_api_help? => false}.merge(args)
18
20
  parse = double(args)
19
21
  format_document doc, parse
20
22
  end
@@ -86,14 +88,102 @@ describe Razor::CLI::Format do
86
88
  "items"=>[{'a' => 'b', 'c' => 'd'},
87
89
  {'b' => 'c', 'e' => 'f'}]}
88
90
  result = format doc
89
- result.should == <<-OUTPUT.rstrip
91
+ result.should ==
92
+ # The framework seems to be adding unnecessary spaces at the end of each data line;
93
+ # Working around this by adding \s to the expectation.
94
+
95
+ # Unicode:
96
+ #┏━━━┳━━━┳━━━┳━━━┓
97
+ #┃ a ┃ c ┃ b ┃ e ┃\s
98
+ #┣━━━╊━━━╊━━━╊━━━┫
99
+ #┃ b ┃ d ┃ ┃ ┃\s
100
+ #┣━━━╊━━━╊━━━╊━━━┫
101
+ #┃ ┃ ┃ c ┃ f ┃\s
102
+ #┗━━━┻━━━┻━━━┻━━━┛
103
+ # ASCII:
104
+ <<-OUTPUT.rstrip
105
+ +---+---+---+---+
106
+ | a | c | b | e |\s
90
107
  +---+---+---+---+
91
- | a | c | b | e |
108
+ | b | d | | |\s
92
109
  +---+---+---+---+
93
- | b | d | | |
94
- | | | c | f |
110
+ | | | c | f |\s
95
111
  +---+---+---+---+
112
+ OUTPUT
113
+ end
114
+
115
+ it "works right with unicode" do
116
+ doc = {"spec"=>"http://api.puppetlabs.com/razor/v1/collections/nodes/log",
117
+ "items"=>[{'a' => 'ᓱᓴᓐ ᐊᒡᓗᒃᑲᖅ'}]}
118
+ result = format doc
119
+ result.should ==
120
+ # The framework seems to be adding unnecessary spaces at the end of each data line;
121
+ # Working around this by adding \s to the expectation.
122
+
123
+ # Unicode:
124
+ #┏━━━━━━━━━━━━┓
125
+ #┃ a ┃\s
126
+ #┣━━━━━━━━━━━━┫
127
+ #┃ ᓱᓴᓐ ᐊᒡᓗᒃᑲᖅ ┃\s
128
+ #┗━━━━━━━━━━━━┛
129
+ # ASCII:
130
+ <<-OUTPUT.rstrip
131
+ +------------+
132
+ | a |\s
133
+ +------------+
134
+ | ᓱᓴᓐ ᐊᒡᓗᒃᑲᖅ |\s
135
+ +------------+
96
136
  OUTPUT
97
137
  end
98
138
  end
139
+
140
+ context 'api help' do
141
+ it "displays the CLI help by default" do
142
+ doc = {"name"=>"some-help", "help" => {"summary"=>"summary here",
143
+ "examples"=>{"api"=>"api example is here", "cli"=>"cli example is here"},
144
+ "full" => "shouldn't show this"},
145
+ "schema" => {"name"=>{"type"=>"string"}}}
146
+ result = format doc, show_command_help?: true
147
+ result.should =~ /cli example is here/
148
+ end
149
+
150
+ it "displays the API help when the --api flag is true" do
151
+ doc = {"name"=>"some-help", "help" => {"summary"=>"summary here",
152
+ "examples"=>{"api"=>"api example is here", "cli"=>"cli example is here"},
153
+ "full" => "shouldn't show this"},
154
+ "schema" => {"name"=>{"type"=>"string"}}}
155
+ result = format doc, show_api_help?: true, show_command_help?: true
156
+ result.should =~ /api example is here/
157
+ end
158
+
159
+ it "displays the full help if on an older server" do
160
+ doc = {"name"=>"some-help", "help" => {"full" => "full help is here"},
161
+ "schema" => {"name"=>{"type"=>"string"}}}
162
+ result = format doc, show_command_help?: true
163
+ result.should =~ /full help is here/
164
+ end
165
+
166
+ it "displays the full help if on an older server and api is specified" do
167
+ doc = {"name"=>"some-help", "help" => {"full" => "full help is here"},
168
+ "schema" => {"name"=>{"type"=>"string"}}}
169
+ result = format doc, show_api_help?: true, show_command_help?: true
170
+ result.should =~ /full help is here/
171
+ end
172
+
173
+ it "skips the 'Examples' section if cli examples are not included" do
174
+ doc = {"name"=>"some-help", "help" => {"summary"=>"summary here",
175
+ "examples"=>{"api"=>"api example is here"},
176
+ "full" => "shouldn't show this"},
177
+ "schema" => {"name"=>{"type"=>"string"}}}
178
+ result = format doc, show_cli_help?: true, show_command_help?: true
179
+ result.should =~ /summary here/
180
+ result.should_not =~ /EXAMPLES/
181
+ end
182
+
183
+ it "errors if help does not exist" do
184
+ doc = {"name"=>"some-help", "schema" => {"name"=>{"type"=>"string"}}}
185
+ expect { format doc, show_cli_help?: true, show_command_help?: true }.
186
+ to raise_error(Razor::CLI::Error, /Could not find help for that entry/)
187
+ end
188
+ end
99
189
  end