rest-object 0.0.1

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.
@@ -0,0 +1,59 @@
1
+ # Module to be included for REST Object
2
+ #
3
+ require_relative 'rest-object/gree_json.rb'
4
+
5
+ module RestObject
6
+
7
+ # response is a Net:HTTPResponse object returned from REST call
8
+ attr_reader :response, :code, :body
9
+
10
+ def initialize(response)
11
+ @response = response
12
+ @code = response.code
13
+ @body = response.body
14
+ end
15
+
16
+ def is_restful?
17
+ begin
18
+ return (JSON.parse(@body).class == Hash)
19
+ rescue
20
+ return false
21
+ end
22
+ end
23
+
24
+ # Verify if @code is 200
25
+ def is_successful?
26
+ @code == "200"
27
+ end
28
+
29
+ # Verify if @code is 4xx
30
+ def is_client_error?
31
+ end
32
+
33
+ # Verify if @code is 5xx
34
+ def is_server_error?
35
+ end
36
+
37
+ # Verify API response body
38
+ def verify_rest_body(expected, content_type = :json)
39
+ if content_type == :json
40
+ GreeJson.check_json_response(expected, @body)
41
+ else
42
+ return (@body == expected)
43
+ end
44
+ end
45
+
46
+ # Verify API response header
47
+ def verify_rest_header(expected)
48
+ end
49
+
50
+ end
51
+
52
+
53
+ # Unit test
54
+ if __FILE__ == $0
55
+ GreeLog.level = Logger::INFO
56
+ GreeLog.echo_to_screen = true
57
+
58
+ end
59
+
@@ -0,0 +1,93 @@
1
+ # convenience functions for dealing with errors and exceptions
2
+
3
+ require 'pp'
4
+
5
+ require_relative 'gree_ruby_extensions.rb'
6
+ require_relative 'gree_logger.rb'
7
+
8
+ module GreeErr
9
+
10
+ # Construct an error message string saying 2 things are not identical
11
+ def self.msg_not_identical(value_name, var1, var2)
12
+ return "#{value_name} is not identical: #1 = #{value_1}, #2 = #{value_2}"
13
+ end
14
+
15
+ # Construct an error message string saying something has an unsupported value
16
+ def self.msg_unsupported(value_name, value)
17
+ return "Unsupported #{value_name}: '#{value}'"
18
+ end
19
+
20
+ # Raise a RuntimeError when 2 things are not identical
21
+ def self.not_identical_raise(value_name, value_1, value_2)
22
+ raise RuntimeError, self.msg_not_identical(value_name, value_1, value_2), caller
23
+ end
24
+
25
+ def self.raise(*args)
26
+ _log_message = ""
27
+ # look for a backtrace to include
28
+ for _arg in args
29
+ if _arg.respond_to? :backtrace
30
+ _log_message << " " << _arg.backtrace.join("\n ")
31
+ end
32
+ end
33
+ # if no backtrace found, add generic
34
+ if _log_message == ""
35
+ _log_message << " " << caller.join("\n ")
36
+ end
37
+ _log_message = "Exception-> " + args.pretty_inspect + _log_message
38
+ GreeLog.error(previous_function_name + "()") {
39
+ _log_message
40
+ }
41
+ Kernel.raise *args
42
+ end
43
+
44
+ # Raise an ArgumentError when an argument has unsupported value
45
+ def self.unsupported_raise(value_name, value)
46
+ raise ArgumentError, self.msg_unsupported(value_name, value), caller
47
+ end
48
+
49
+ # Execute block, ignoring the specified exception type (default: all exceptions)
50
+ def self.with_ignored_exceptions(exception_types = StandardError)
51
+ begin
52
+ yield
53
+ rescue exception_types => _the_exception
54
+ # Ignore the exception
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ # ======================
61
+ # SELF-TEST
62
+ # ======================
63
+
64
+ if $0 == __FILE__
65
+ def test
66
+ GreeLog.handler=Logger.new(
67
+ File.join(File.expand_path(File.dirname(__FILE__)), 'test-' + Time.now.strftime('%Y-%m-%d-%H%M%S') + '.log')
68
+ )
69
+
70
+ begin
71
+ GreeErr.raise 'this is an error message'
72
+ rescue
73
+ end
74
+
75
+ begin
76
+ GreeErr.raise ArgumentError
77
+ rescue
78
+ end
79
+
80
+ begin
81
+ GreeErr.raise ArgumentError, 'this is a message for ArgumentError exception'
82
+ rescue
83
+ end
84
+
85
+ begin
86
+ GreeErr.raise
87
+ rescue
88
+ end
89
+ end
90
+
91
+ test
92
+
93
+ end
@@ -0,0 +1,79 @@
1
+ # Utilities for JSON handling
2
+
3
+ require_relative "gree_logger.rb"
4
+ require 'json'
5
+
6
+ module GreeJson
7
+
8
+ # Validate a JSON response, comparing to an expected hash
9
+ # TODO: add strict parm to check for extra keys
10
+ def self.check_json_response(expected, response)
11
+ begin
12
+ result = JSON.parse(response)
13
+ _validate_json_or_json_array(expected, result)
14
+ rescue => ex
15
+ GreeLog.puts "EXCEPTION: #{ex.message}\n"
16
+ GreeLog.puts "EXPECTED\n#{expected.inspect}\n"
17
+ GreeLog.puts "ACTUAL\n#{response}\nEND"
18
+ # rethrow the message to remove the recursive stack trace
19
+ raise ex.message
20
+ end
21
+ end
22
+
23
+ def self._validate_json_or_json_array(expected, actual)
24
+ if actual.class == Array
25
+ _validate_json_array(expected, actual, actual.count)
26
+ else
27
+ _validate_json(expected, actual)
28
+ end
29
+ end
30
+
31
+ def self._validate_json(expected, actual)
32
+ if actual.nil?
33
+ raise "missing field(s) in response: expected=#{expected} - actual == nil"
34
+ end
35
+ expected.each do |k, v|
36
+ a = actual[k.to_s]
37
+ #if a.nil?
38
+ if !actual.has_key?(k.to_s)
39
+ raise "missing \"#{k}\" property in JSON response, expected: #{v.inspect}"
40
+ end
41
+ case v
42
+ when Hash
43
+ if a.class != Hash
44
+ raise "got #{a.class} instead of JSON object for #{k}"
45
+ end
46
+ _validate_json(v, a)
47
+ when Array
48
+ if a.class != Array
49
+ raise "got JSON object instead of array for #{k}"
50
+ end
51
+ _validate_json_array(v, a, k.to_s)
52
+ when Regexp
53
+ a.should match v
54
+ else
55
+ a.should == v unless v == :any
56
+ end
57
+ end
58
+ end
59
+
60
+ def self._validate_json_array(expected, actual, k)
61
+ if actual.class != Array
62
+ raise "#{k} in response is not an array as expected"
63
+ end
64
+ if expected.count != actual.count
65
+ raise "Error in #{k} array: expected #{expected.count} items, got #{actual.count}"
66
+ end
67
+ expected.each_index do |i|
68
+ _validate_json(expected[i], actual[i])
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+
75
+ # Unit test
76
+ if __FILE__ == $0
77
+
78
+ end
79
+
@@ -0,0 +1,101 @@
1
+ # Utilities for log handling
2
+
3
+ require 'logger'
4
+ require 'pp'
5
+
6
+ class GreeLog
7
+
8
+ @@logger=nil
9
+ @@echo_to_screen = false
10
+
11
+ def self.close
12
+ @@logger.close
13
+ @@logger = nil
14
+ end
15
+
16
+ def self.echo_to_screen
17
+ return @@echo_to_screen
18
+ end
19
+
20
+ def self.echo_to_screen=(value)
21
+ @@echo_to_screen=value
22
+ end
23
+
24
+ def self.logger
25
+ return @@logger
26
+ end
27
+
28
+ def self.logger=(logger_object)
29
+ @@logger=logger_object
30
+ end
31
+
32
+ def self.logging?
33
+ return !@@logger.nil?
34
+ end
35
+
36
+ def self.method_missing(method_name, *method_args, &block)
37
+ if @@echo_to_screen
38
+ puts "[#{Time.now.strftime('%H:%M:%S')}] #{method_name.to_s.upcase} -- #{previous_function_name}: #{method_args.inspect} #{(block ? '{' + block.to_s + '}' : '')}"
39
+ end
40
+ if @@logger
41
+ @@logger.progname = previous_function_name
42
+ @@logger.send(method_name, *method_args, &block)
43
+ end
44
+ end
45
+
46
+ # print out a message without escaping the the quotes, newlines ...
47
+ def self.puts(message)
48
+ if @@echo_to_screen
49
+ Kernel.puts "#{message}"
50
+ end
51
+ if @@logger
52
+ @@logger.progname = previous_function_name
53
+ @@logger.send("info", message)
54
+ end
55
+ end
56
+
57
+ # Returns the name of the function from which this method was called, by looking at the call stack. If call stack
58
+ # is empty, returns "(anonymous)"
59
+ #
60
+ # def foo
61
+ # puts current_function_name
62
+ # end
63
+ #
64
+ # foo -> "foo"
65
+ #
66
+ # current_function_name -> "(anonymous)"
67
+ #
68
+ # Used for logging and error reporting, so that generic code can record the name of the currently running function.
69
+
70
+ def self.current_function_name
71
+ return caller()[0] =~ /in `([^']+)'/ ? $1 : '(anonymous)'
72
+ end
73
+
74
+ # Returns the name of the function two levels down in the call stack. If call stack
75
+ # has insufficient depth, returns "(anonymous)"
76
+ #
77
+ # def foo
78
+ # puts previous_function_name
79
+ # end
80
+ #
81
+ # def bar
82
+ # foo
83
+ # end
84
+ #
85
+ # bar -> "bar"
86
+ #
87
+ # foo -> "(anonymous)"
88
+ #
89
+ # previous_function_name => "(anonymous)"
90
+ #
91
+ # Used for setting up a centralized error handler that calls a centralized logger.
92
+
93
+ def self.previous_function_name
94
+ if caller().length < 2
95
+ return '(anonymous)'
96
+ else
97
+ return caller()[1] =~ /in `([^']+)'/ ? $1 : '(anonymous)'
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,73 @@
1
+ # Gree Ruby Extensions
2
+ # This file provides various convenient extensions to Ruby's built-in objects and libraries
3
+
4
+ unless defined? "INFINITY"
5
+ INFINITY = 1.0/0
6
+ end
7
+
8
+ unless defined? "NaN"
9
+ NaN = 0.0/0
10
+ end
11
+
12
+ class Array
13
+ # Same as <tt>Array.detect</tt>, but scans from end of array to beginning.
14
+ def reverse_detect(&block)
15
+ self.reverse_each {|_element|
16
+ if block.call(_element)
17
+ return _element
18
+ end
19
+ }
20
+ return nil
21
+ end
22
+ end
23
+
24
+ class Hash
25
+ def hash_value_missing?(key)
26
+ # test if key is missing, or key value is nil or empty string
27
+ return !self.has_key?(key) || self[key]=="" || self[key].nil?
28
+ end
29
+ end
30
+
31
+ # Returns the name of the function from which this method was called, by looking at the call stack. If call stack
32
+ # is empty, returns "(anonymous)"
33
+ #
34
+ # def foo
35
+ # puts current_function_name
36
+ # end
37
+ #
38
+ # foo -> "foo"
39
+ #
40
+ # current_function_name -> "(anonymous)"
41
+ #
42
+ # Used for logging and error reporting, so that generic code can record the name of the currently running function.
43
+
44
+ def current_function_name
45
+ return caller()[0] =~ /in `([^']+)'/ ? $1 : '(anonymous)'
46
+ end
47
+
48
+ # Returns the name of the function two levels down in the call stack. If call stack
49
+ # has insufficient depth, returns "(anonymous)"
50
+ #
51
+ # def foo
52
+ # puts previous_function_name
53
+ # end
54
+ #
55
+ # def bar
56
+ # foo
57
+ # end
58
+ #
59
+ # bar -> "bar"
60
+ #
61
+ # foo -> "(anonymous)"
62
+ #
63
+ # previous_function_name => "(anonymous)"
64
+ #
65
+ # Used for setting up a centralized error handler that calls a centralized logger.
66
+
67
+ def previous_function_name
68
+ if caller().length < 2
69
+ return '(anonymous)'
70
+ else
71
+ return caller()[1] =~ /in `([^']+)'/ ? $1 : '(anonymous)'
72
+ end
73
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rest-object
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chaoyi Chen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-27 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: REST API Object DSL for RESTful API testing
15
+ email: chaoyi.chen@gree.net
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/rest-object.rb
21
+ - lib/rest-object/gree_logger.rb
22
+ - lib/rest-object/gree_ruby_extensions.rb
23
+ - lib/rest-object/gree_json.rb
24
+ - lib/rest-object/gree_err.rb
25
+ homepage: http://rubygems.org/gems/hola
26
+ licenses: []
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 1.8.24
46
+ signing_key:
47
+ specification_version: 3
48
+ summary: REST API Object DSL for RESTful API testing
49
+ test_files: []