haveapi 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +6 -6
  4. data/haveapi.gemspec +13 -13
  5. data/lib/haveapi/action.rb +140 -158
  6. data/lib/haveapi/action_state.rb +2 -6
  7. data/lib/haveapi/actions/default.rb +8 -10
  8. data/lib/haveapi/api.rb +2 -1
  9. data/lib/haveapi/authentication/base.rb +5 -8
  10. data/lib/haveapi/authentication/basic/provider.rb +4 -5
  11. data/lib/haveapi/authentication/chain.rb +19 -17
  12. data/lib/haveapi/authentication/oauth2/config.rb +12 -32
  13. data/lib/haveapi/authentication/oauth2/provider.rb +20 -30
  14. data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +1 -2
  15. data/lib/haveapi/authentication/token/action_config.rb +5 -3
  16. data/lib/haveapi/authentication/token/config.rb +5 -5
  17. data/lib/haveapi/authentication/token/provider.rb +33 -37
  18. data/lib/haveapi/authorization.rb +5 -4
  19. data/lib/haveapi/client_example.rb +11 -14
  20. data/lib/haveapi/client_examples/curl.rb +37 -37
  21. data/lib/haveapi/client_examples/fs_client.rb +29 -31
  22. data/lib/haveapi/client_examples/http.rb +35 -36
  23. data/lib/haveapi/client_examples/js_client.rb +62 -63
  24. data/lib/haveapi/client_examples/php_client.rb +77 -76
  25. data/lib/haveapi/client_examples/ruby_cli.rb +30 -30
  26. data/lib/haveapi/client_examples/ruby_client.rb +26 -26
  27. data/lib/haveapi/common.rb +3 -4
  28. data/lib/haveapi/context.rb +11 -10
  29. data/lib/haveapi/example.rb +9 -4
  30. data/lib/haveapi/example_list.rb +2 -2
  31. data/lib/haveapi/exceptions.rb +1 -1
  32. data/lib/haveapi/extensions/action_exceptions.rb +2 -2
  33. data/lib/haveapi/extensions/base.rb +1 -3
  34. data/lib/haveapi/extensions/exception_mailer.rb +260 -257
  35. data/lib/haveapi/hooks.rb +40 -39
  36. data/lib/haveapi/metadata.rb +1 -1
  37. data/lib/haveapi/model_adapter.rb +16 -27
  38. data/lib/haveapi/model_adapters/active_record.rb +59 -69
  39. data/lib/haveapi/output_formatter.rb +7 -7
  40. data/lib/haveapi/output_formatters/base.rb +2 -4
  41. data/lib/haveapi/parameters/resource.rb +7 -7
  42. data/lib/haveapi/parameters/typed.rb +6 -9
  43. data/lib/haveapi/params.rb +38 -45
  44. data/lib/haveapi/resource.rb +8 -8
  45. data/lib/haveapi/resources/action_state.rb +11 -19
  46. data/lib/haveapi/server.rb +102 -107
  47. data/lib/haveapi/spec/api_response.rb +1 -1
  48. data/lib/haveapi/spec/helpers.rb +1 -1
  49. data/lib/haveapi/spec/mock_action.rb +11 -10
  50. data/lib/haveapi/spec/spec_methods.rb +9 -8
  51. data/lib/haveapi/tasks/yard.rb +2 -2
  52. data/lib/haveapi/types.rb +0 -3
  53. data/lib/haveapi/validator.rb +6 -3
  54. data/lib/haveapi/validator_chain.rb +9 -8
  55. data/lib/haveapi/validators/acceptance.rb +6 -6
  56. data/lib/haveapi/validators/confirmation.rb +2 -3
  57. data/lib/haveapi/validators/exclusion.rb +1 -1
  58. data/lib/haveapi/validators/format.rb +1 -1
  59. data/lib/haveapi/validators/inclusion.rb +1 -1
  60. data/lib/haveapi/validators/length.rb +12 -11
  61. data/lib/haveapi/validators/numericality.rb +14 -13
  62. data/lib/haveapi/validators/presence.rb +4 -3
  63. data/lib/haveapi/version.rb +2 -2
  64. data/lib/haveapi.rb +2 -3
  65. data/spec/.rubocop.yml +4 -0
  66. data/spec/action/dsl_spec.rb +18 -18
  67. data/spec/authorization_spec.rb +8 -8
  68. data/spec/common_spec.rb +2 -1
  69. data/spec/documentation_spec.rb +2 -9
  70. data/spec/envelope_spec.rb +2 -2
  71. data/spec/hooks_spec.rb +12 -12
  72. data/spec/parameters/typed_spec.rb +6 -6
  73. data/spec/params_spec.rb +22 -24
  74. data/spec/resource_spec.rb +5 -7
  75. data/spec/spec_helper.rb +0 -1
  76. data/spec/validators/acceptance_spec.rb +1 -1
  77. data/spec/validators/confirmation_spec.rb +5 -5
  78. data/spec/validators/exclusion_spec.rb +3 -3
  79. data/spec/validators/format_spec.rb +2 -2
  80. data/spec/validators/inclusion_spec.rb +4 -4
  81. data/spec/validators/length_spec.rb +23 -23
  82. data/spec/validators/numericality_spec.rb +13 -13
  83. data/spec/validators/presence_spec.rb +3 -3
  84. metadata +49 -48
@@ -33,8 +33,8 @@ module HaveAPI
33
33
  # @param blacklist [Array<Symbol>] allow all parameters except listed ones
34
34
  def input(whitelist: nil, blacklist: nil)
35
35
  @input = {
36
- whitelist: whitelist,
37
- blacklist: blacklist,
36
+ whitelist:,
37
+ blacklist:
38
38
  }
39
39
  end
40
40
 
@@ -43,8 +43,8 @@ module HaveAPI
43
43
  # @param blacklist [Array<Symbol>] allow all parameters except listed ones
44
44
  def output(whitelist: nil, blacklist: nil)
45
45
  @output = {
46
- whitelist: whitelist,
47
- blacklist: blacklist,
46
+ whitelist:,
47
+ blacklist:
48
48
  }
49
49
  end
50
50
 
@@ -75,6 +75,7 @@ module HaveAPI
75
75
  end
76
76
 
77
77
  private
78
+
78
79
  def filter_inner(allowed_params, direction, params, format)
79
80
  allowed = {}
80
81
 
@@ -1,5 +1,5 @@
1
1
  module HaveAPI
2
- module ClientExamples ; end
2
+ module ClientExamples; end
3
3
 
4
4
  # All client example classes should inherit this class. Depending on the client,
5
5
  # the subclass may choose to implement either method `example` or `request` and
@@ -39,13 +39,13 @@ module HaveAPI
39
39
  end
40
40
 
41
41
  # Shortcut to {ClientExample#init}
42
- def init(*args)
43
- new(*args).init
42
+ def init(*)
43
+ new(*).init
44
44
  end
45
45
 
46
46
  # Shortcut to {ClientExample#auth}
47
47
  def auth(*args)
48
- new(*args[0..-3]).auth(*args[-2..-1])
48
+ new(*args[0..-3]).auth(*args[-2..])
49
49
  end
50
50
 
51
51
  # Shortcut to {ClientExample#example}
@@ -68,30 +68,27 @@ module HaveAPI
68
68
  @resource_path, @resource, @action_name, @action = args
69
69
  end
70
70
 
71
- def init
71
+ def init; end
72
72
 
73
- end
74
-
75
- def auth(method, desc)
76
-
77
- end
73
+ def auth(method, desc); end
78
74
 
79
75
  def version_url
80
76
  File.join(base_url, "v#{version}", '/')
81
77
  end
82
78
 
83
79
  protected
80
+
84
81
  # @param password [Boolean] include password parameter
85
82
  # @return [Hash<String, String>] parameter => example value
86
83
  def auth_token_credentials(desc, password: true)
87
- passwords = %i(password pass passwd)
88
- params = desc[:resources][:token][:actions]['request'][:input][:parameters].keys - %i(lifetime interval)
84
+ passwords = %i[password pass passwd]
85
+ params = desc[:resources][:token][:actions]['request'][:input][:parameters].keys - %i[lifetime interval]
89
86
 
90
87
  unless password
91
88
  params.reject! { |param| passwords.include?(param) }
92
89
  end
93
90
 
94
- Hash[params.map do |param|
91
+ params.to_h do |param|
95
92
  value =
96
93
  if passwords.include?(param)
97
94
  'secret'
@@ -100,7 +97,7 @@ module HaveAPI
100
97
  end
101
98
 
102
99
  [param, value]
103
- end]
100
+ end
104
101
  end
105
102
  end
106
103
  end
@@ -14,34 +14,34 @@ module HaveAPI::ClientExamples
14
14
  def auth(method, desc)
15
15
  case method
16
16
  when :basic
17
- <<END
18
- # Password is asked on standard input
19
- $ curl --request OPTIONS \\
20
- --user username \\
21
- '#{base_url}'
22
- Password: secret
17
+ <<~END
18
+ # Password is asked on standard input
19
+ $ curl --request OPTIONS \\
20
+ --user username \\
21
+ '#{base_url}'
22
+ Password: secret
23
23
 
24
- # Password given on the command line
25
- $ curl --request OPTIONS \\
26
- --user username:secret \\
27
- '#{base_url}'
28
- END
24
+ # Password given on the command line
25
+ $ curl --request OPTIONS \\
26
+ --user username:secret \\
27
+ '#{base_url}'
28
+ END
29
29
 
30
30
  when :token
31
31
  login = auth_token_credentials(desc).merge(lifetime: 'fixed')
32
32
 
33
- <<END
34
- # Acquire the token
35
- $ curl --request POST \\
36
- --header 'Content-Type: application/json' \\
37
- --data-binary "#{format_data(token: login)}" \\
38
- '#{File.join(base_url, '_auth', 'token', 'tokens')}'
33
+ <<~END
34
+ # Acquire the token
35
+ $ curl --request POST \\
36
+ --header 'Content-Type: application/json' \\
37
+ --data-binary "#{format_data(token: login)}" \\
38
+ '#{File.join(base_url, '_auth', 'token', 'tokens')}'
39
39
 
40
- # Use a previously acquired token
41
- $ curl --request OPTIONS \\
42
- --header '#{desc[:http_header]}: thetoken' \\
43
- '#{base_url}'
44
- END
40
+ # Use a previously acquired token
41
+ $ curl --request OPTIONS \\
42
+ --header '#{desc[:http_header]}: thetoken' \\
43
+ '#{base_url}'
44
+ END
45
45
 
46
46
  when :oauth2
47
47
  '# See RFC 6749 for authorization process and RFC 6750 for access token usage.'
@@ -50,32 +50,32 @@ END
50
50
 
51
51
  def request(sample)
52
52
  url = File.join(
53
- base_url,
54
- resolve_path(
55
- action[:method],
56
- action[:path],
57
- sample[:path_params] || [],
58
- sample[:request]
59
- )
53
+ base_url,
54
+ resolve_path(
55
+ action[:method],
56
+ action[:path],
57
+ sample[:path_params] || [],
58
+ sample[:request]
59
+ )
60
60
  )
61
61
 
62
62
  data = format_data({
63
- action[:input][:namespace] => sample[:request],
63
+ action[:input][:namespace] => sample[:request]
64
64
  })
65
65
 
66
- <<END
67
- $ curl --request #{action[:method]} \\
68
- --data-binary "#{data}" \\
69
- '#{url}'
70
- END
66
+ <<~END
67
+ $ curl --request #{action[:method]} \\
68
+ --data-binary "#{data}" \\
69
+ '#{url}'
70
+ END
71
71
  end
72
72
 
73
73
  def response(sample)
74
74
  JSON.pretty_generate({
75
75
  status: sample[:status],
76
76
  message: sample[:message],
77
- response: {action[:output][:namespace] => sample[:response]},
78
- errors: sample[:errors],
77
+ response: { action[:output][:namespace] => sample[:response] },
78
+ errors: sample[:errors]
79
79
  })
80
80
  end
81
81
 
@@ -13,27 +13,27 @@ module HaveAPI::ClientExamples
13
13
  def auth(method, desc)
14
14
  case method
15
15
  when :basic
16
- <<END
17
- # Provide credentials as file system options
18
- #{init} -o auth_method=basic,user=myuser,password=secret
16
+ <<~END
17
+ # Provide credentials as file system options
18
+ #{init} -o auth_method=basic,user=myuser,password=secret
19
19
 
20
- # If username or password isn't provided, the user is asked on stdin
21
- #{init} -o auth_method=basic,user=myuser
22
- Password: secret
23
- END
20
+ # If username or password isn't provided, the user is asked on stdin
21
+ #{init} -o auth_method=basic,user=myuser
22
+ Password: secret
23
+ END
24
24
 
25
25
  when :token
26
- <<END
27
- # Authenticate using username and password
28
- #{init} -o auth_method=token,user=myuser
29
- Password: secret
26
+ <<~END
27
+ # Authenticate using username and password
28
+ #{init} -o auth_method=token,user=myuser
29
+ Password: secret
30
30
 
31
- # If you have generated a token, you can use it
32
- #{init} -o auth_method=token,token=yourtoken
31
+ # If you have generated a token, you can use it
32
+ #{init} -o auth_method=token,token=yourtoken
33
33
 
34
- # Note that the file system can read config file from haveapi-client, so if
35
- # you set up authentication there, the file system will use it.
36
- END
34
+ # Note that the file system can read config file from haveapi-client, so if
35
+ # you set up authentication there, the file system will use it.
36
+ END
37
37
 
38
38
  when :oauth2
39
39
  '# OAuth2 is not supported by haveapi-fs.'
@@ -47,9 +47,7 @@ END
47
47
 
48
48
  unless class_action?
49
49
  if !sample[:path_params] || sample[:path_params].empty?
50
- fail "example {#{sample}} of action #{resource_path.join('.')}"+
51
- ".#{action_name} is for an instance action but does not include "+
52
- "URL parameters"
50
+ raise "example {#{sample}} of action #{resource_path.join('.')}.#{action_name} is for an instance action but does not include URL parameters"
53
51
  end
54
52
 
55
53
  path << sample[:path_params].first.to_s
@@ -69,29 +67,29 @@ END
69
67
  end
70
68
 
71
69
  cmd << "\n# Execute the action"
72
- cmd << "$ echo 1 > exec"
70
+ cmd << '$ echo 1 > exec'
73
71
 
74
72
  cmd << "\n# Query the action's result"
75
- cmd << "$ cat status"
73
+ cmd << '$ cat status'
76
74
  cmd << (sample[:status] ? '1' : '0')
77
75
 
78
76
  if sample[:status]
79
77
  if sample[:response] && !sample[:response].empty? \
80
- && %i(hash object).include?(action[:output][:layout])
78
+ && %i[hash object].include?(action[:output][:layout])
81
79
  cmd << "\n# Query the output parameters"
82
80
 
83
81
  sample[:response].each do |k, v|
84
82
  cmd << "$ cat output/#{k}"
85
83
 
86
- if v === true
87
- cmd << '1'
84
+ cmd << if v === true
85
+ '1'
88
86
 
89
- elsif v === false
90
- cmd << '0'
87
+ elsif v === false
88
+ '0'
91
89
 
92
- else
93
- cmd << "#{v.to_s}"
94
- end
90
+ else
91
+ v.to_s
92
+ end
95
93
 
96
94
  cmd << "\n"
97
95
  end
@@ -99,11 +97,11 @@ END
99
97
 
100
98
  else
101
99
  cmd << "\n# Get the error message"
102
- cmd << "$ cat message"
100
+ cmd << '$ cat message'
103
101
  cmd << sample[:message]
104
102
 
105
103
  cmd << "\n# Parameter errors can be seen in the `errors` directory"
106
- cmd << "$ ls errors"
104
+ cmd << '$ ls errors'
107
105
  cmd << (sample[:errors] || {}).keys.join("\n")
108
106
  end
109
107
 
@@ -1,4 +1,3 @@
1
- require 'pp'
2
1
  require 'cgi'
3
2
  require 'rack/utils'
4
3
  require 'haveapi/client_example'
@@ -10,61 +9,61 @@ module HaveAPI::ClientExamples
10
9
  order 100
11
10
 
12
11
  def init
13
- <<END
14
- OPTIONS /v#{version}/ HTTP/1.1
15
- Host: #{host}
12
+ <<~END
13
+ OPTIONS /v#{version}/ HTTP/1.1
14
+ Host: #{host}
16
15
 
17
- END
16
+ END
18
17
  end
19
18
 
20
19
  def auth(method, desc)
21
20
  case method
22
21
  when :basic
23
- <<END
24
- GET / HTTP/1.1
25
- Host: #{host}
26
- Authorization: Basic dXNlcjpzZWNyZXQ=
22
+ <<~END
23
+ GET / HTTP/1.1
24
+ Host: #{host}
25
+ Authorization: Basic dXNlcjpzZWNyZXQ=
27
26
 
28
- END
27
+ END
29
28
 
30
29
  when :token
31
30
  login = auth_token_credentials(desc).merge(lifetime: 'fixed')
32
31
 
33
- <<END
34
- POST /_auth/token/tokens HTTP/1.1
35
- Host: #{host}
36
- Content-Type: application/json
32
+ <<~END
33
+ POST /_auth/token/tokens HTTP/1.1
34
+ Host: #{host}
35
+ Content-Type: application/json
37
36
 
38
- #{JSON.pretty_generate({token: login})}
39
- END
37
+ #{JSON.pretty_generate({ token: login })}
38
+ END
40
39
 
41
40
  when :oauth2
42
- <<END
43
- # 1) Request authorization code
44
- GET #{desc[:authorize_path]}?response_type=code&client_id=$client_id&state=$state&redirect_uri=$client_redirect_uri HTTP/1.1
45
- Host: #{host}
41
+ <<~END
42
+ # 1) Request authorization code
43
+ GET #{desc[:authorize_path]}?response_type=code&client_id=$client_id&state=$state&redirect_uri=$client_redirect_uri HTTP/1.1
44
+ Host: #{host}
46
45
 
47
- # 2) The user logs in using this API
46
+ # 2) The user logs in using this API
48
47
 
49
- # 3) The API then redirects the user back to the client application
50
- GET $client_redirect_uri?code=$authorization_code&state=$state
51
- Host: client-application
48
+ # 3) The API then redirects the user back to the client application
49
+ GET $client_redirect_uri?code=$authorization_code&state=$state
50
+ Host: client-application
52
51
 
53
- # 4) The client application requests access token
54
- POST #{desc[:token_path]}
55
- Content-Type: application/x-www-form-urlencoded
52
+ # 4) The client application requests access token
53
+ POST #{desc[:token_path]}
54
+ Content-Type: application/x-www-form-urlencoded
56
55
 
57
- grant_type=authorization_code&code=$authorization_code&redirect_uri=$client_redirect_uri&client_id=$client_id&client_secret=$client_secret
58
- END
56
+ grant_type=authorization_code&code=$authorization_code&redirect_uri=$client_redirect_uri&client_id=$client_id&client_secret=$client_secret
57
+ END
59
58
  end
60
59
  end
61
60
 
62
61
  def request(sample)
63
62
  path = resolve_path(
64
- action[:method],
65
- action[:path],
66
- sample[:path_params] || [],
67
- sample[:request]
63
+ action[:method],
64
+ action[:path],
65
+ sample[:path_params] || [],
66
+ sample[:request]
68
67
  )
69
68
 
70
69
  req = "#{action[:method]} #{path} HTTP/1.1\n"
@@ -72,7 +71,7 @@ END
72
71
  req << "Content-Type: application/json\n\n"
73
72
 
74
73
  if action[:method] != 'GET' && sample[:request] && !sample[:request].empty?
75
- req << JSON.pretty_generate({action[:input][:namespace] => sample[:request]})
74
+ req << JSON.pretty_generate({ action[:input][:namespace] => sample[:request] })
76
75
  end
77
76
 
78
77
  req
@@ -82,8 +81,8 @@ END
82
81
  content = JSON.pretty_generate({
83
82
  status: sample[:status],
84
83
  message: sample[:message],
85
- response: {action[:output][:namespace] => sample[:response]},
86
- errors: sample[:errors],
84
+ response: { action[:output][:namespace] => sample[:response] },
85
+ errors: sample[:errors]
87
86
  })
88
87
 
89
88
  status_msg = Rack::Utils::HTTP_STATUS_CODES[sample[:http_status]]
@@ -7,61 +7,61 @@ module HaveAPI::ClientExamples
7
7
  order 10
8
8
 
9
9
  def init
10
- <<END
11
- import HaveAPI from 'haveapi-client'
10
+ <<~END
11
+ import HaveAPI from 'haveapi-client'
12
12
 
13
- var api = new HaveAPI.Client("#{base_url}", {version: "#{version}"});
14
- END
13
+ var api = new HaveAPI.Client("#{base_url}", {version: "#{version}"});
14
+ END
15
15
  end
16
16
 
17
17
  def auth(method, desc)
18
18
  case method
19
19
  when :basic
20
- <<END
21
- #{init}
20
+ <<~END
21
+ #{init}
22
22
 
23
- api.authenticate("basic", {
24
- user: "user",
25
- password: "secret"
26
- }, function (client, status) {
27
- console.log("Authenticated?", status);
28
- });
29
- END
23
+ api.authenticate("basic", {
24
+ user: "user",
25
+ password: "secret"
26
+ }, function (client, status) {
27
+ console.log("Authenticated?", status);
28
+ });
29
+ END
30
30
 
31
31
  when :token
32
- <<END
33
- #{init}
34
-
35
- // Request a new token
36
- api.authenticate("token", {
37
- #{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(",\n ")}
38
- }, function (client, status) {
39
- console.log("Authenticated?", status);
40
-
41
- if (status)
42
- console.log("Token is", client.authProvider.token);
43
- });
44
-
45
- // Use an existing token
46
- api.authenticate("token", {
47
- token: "qwertyuiop..."
48
- }, function (client, status) {
49
- console.log("Authenticated?", status);
50
- });
51
- END
32
+ <<~END
33
+ #{init}
34
+
35
+ // Request a new token
36
+ api.authenticate("token", {
37
+ #{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(",\n ")}
38
+ }, function (client, status) {
39
+ console.log("Authenticated?", status);
40
+
41
+ if (status)
42
+ console.log("Token is", client.authProvider.token);
43
+ });
44
+
45
+ // Use an existing token
46
+ api.authenticate("token", {
47
+ token: "qwertyuiop..."
48
+ }, function (client, status) {
49
+ console.log("Authenticated?", status);
50
+ });
51
+ END
52
52
 
53
53
  when :oauth2
54
- <<END
55
- #{init}
56
- // The JavaScript client must be configured with OAuth2 access token, it does not
57
- // support the authorization procedure to obtain a new access token.
58
- var accessToken = {
59
- access_token: "the access token"
60
- };
61
-
62
- // The client is authenticated immediately, no need for a callback
63
- api.authenticate("oauth2", {access_token: accessToken});
64
- END
54
+ <<~END
55
+ #{init}
56
+ // The JavaScript client must be configured with OAuth2 access token, it does not
57
+ // support the authorization procedure to obtain a new access token.
58
+ var accessToken = {
59
+ access_token: "the access token"
60
+ };
61
+
62
+ // The client is authenticated immediately, no need for a callback
63
+ api.authenticate("oauth2", {access_token: accessToken});
64
+ END
65
65
  end
66
66
  end
67
67
 
@@ -82,14 +82,14 @@ END
82
82
  callback = "function (client, reply) {\n"
83
83
  callback << " console.log('Response', reply);\n"
84
84
 
85
- if sample[:status]
86
- callback << response(sample)
85
+ callback << if sample[:status]
86
+ response(sample)
87
87
 
88
- else
89
- callback << error(sample)
90
- end
88
+ else
89
+ error(sample)
90
+ end
91
91
 
92
- callback << "}"
92
+ callback << '}'
93
93
 
94
94
  out << callback.strip
95
95
  out << ');'
@@ -117,30 +117,30 @@ END
117
117
  when :object
118
118
  out << " // reply is an instance of HaveAPI.Client.ResourceInstance\n"
119
119
 
120
- (sample[:response] || {}).each do |k, v|
121
- param = action[:output][:parameters][k]
120
+ (sample[:response] || {}).each do |pn, pv|
121
+ param = action[:output][:parameters][pn]
122
122
 
123
123
  if param[:type] == 'Resource'
124
- out << " // reply.#{k} = HaveAPI.Client.ResourceInstance("
124
+ out << " // reply.#{pn} = HaveAPI.Client.ResourceInstance("
125
125
  out << "resource: #{param[:resource].join('.')}, "
126
126
 
127
- if v.is_a?(::Hash)
128
- out << v.map { |k,v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
129
- else
130
- out << "id: #{v}"
131
- end
127
+ out << if pv.is_a?(::Hash)
128
+ pv.map { |k, v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
129
+ else
130
+ "id: #{pv}"
131
+ end
132
132
 
133
133
  out << ")\n"
134
134
 
135
- elsif param[:type] == 'Custom' && (v.is_a?(::Hash) || v.is_a?(::Array))
136
- json = JSON.pretty_generate(v).split("\n").map do |v|
135
+ elsif param[:type] == 'Custom' && (pv.is_a?(::Hash) || pv.is_a?(::Array))
136
+ json = JSON.pretty_generate(pv).split("\n").map do |v|
137
137
  " // #{v}"
138
138
  end.join("\n")
139
139
 
140
- out << " // reply.#{k} = #{json}"
140
+ out << " // reply.#{pn} = #{json}"
141
141
 
142
142
  else
143
- out << " // reply.#{k} = #{PP.pp(v, '')}"
143
+ out << " // reply.#{pn} = #{PP.pp(pv, '')}"
144
144
  end
145
145
  end
146
146
 
@@ -149,7 +149,6 @@ END
149
149
  end
150
150
 
151
151
  out
152
-
153
152
  end
154
153
 
155
154
  def error(sample)