json2ruby 0.1.0 → 0.1.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.
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  coverage
2
2
  testjson
3
3
  classes
4
+ doc
4
5
  *.gem
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json2ruby (0.1.0)
4
+ json2ruby (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # json2ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/tomdionysus/json2ruby.svg?branch=master)](https://travis-ci.org/tomdionysus/json2ruby) [![Coverage Status](https://coveralls.io/repos/tomdionysus/json2ruby/badge.svg?branch=master&service=github)](https://coveralls.io/github/tomdionysus/json2ruby?branch=master)
3
+ [![Build Status](https://travis-ci.org/tomdionysus/json2ruby.svg?branch=master)](https://travis-ci.org/tomdionysus/json2ruby) [![Coverage Status](https://coveralls.io/repos/tomdionysus/json2ruby/badge.svg?branch=master&service=github)](https://coveralls.io/github/tomdionysus/json2ruby?branch=master) [![Gem Version](https://badge.fury.io/rb/json2ruby.svg)](http://badge.fury.io/rb/json2ruby)
4
4
 
5
5
  A ruby rool for generating POROs from JSON data. It is intended to generate ruby model classes/modules from existing JSON data, e.g. responses from an API.
6
6
 
@@ -11,7 +11,7 @@ The tool will 'fold down' objects with identical fields - i.e. if an object has
11
11
  ## Installation
12
12
 
13
13
  ```bash
14
- git clone git@github.com:tomdionysus/json2ruby.git
14
+ gem install json2ruby
15
15
  ```
16
16
 
17
17
  ## Usage
@@ -69,6 +69,14 @@ end
69
69
 
70
70
  The option `-N, --forcenumeric` can be useful to fold down identical types where an attribute which is a float happens to have an integer value, to avoid generating two identical types.
71
71
 
72
+ ## Documentation
73
+
74
+ Regenerate the documentation with 'rdoc':
75
+
76
+ ```bash
77
+ rdoc
78
+ ```
79
+
72
80
  ## Contributing
73
81
 
74
82
  1. Fork it
@@ -1,22 +1,33 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  module JSON2Ruby
4
+ # The Attribute class represents a field on an Entity - i.e. A field name and associated type.
4
5
  class Attribute
5
- attr_accessor :name, :original_name, :ruby_type
6
+ # The String name of the Attribute
7
+ attr_accessor :name
8
+ # The original String name of the Array in the JSON ([^A-Za-z0-9_] are replaced with '_')
9
+ attr_accessor :original_name
10
+ # The type of the attribute, i.e. a Entity, Collection or Primitive instance
11
+ attr_accessor :ruby_type
6
12
 
13
+ # The short name is 'Attribute'
7
14
  def self.short_name
8
15
  "Attribute"
9
16
  end
10
17
 
18
+ # Create a new attribute with the supplied String name and optional String type name.
19
+ # If the type is not supplied or nil, if will be assigned '_unknown'
11
20
  def initialize(name, ruby_type = nil)
12
21
  @name = name
13
22
  @ruby_type = ruby_type || "_unknown"
14
23
  end
15
24
 
25
+ # Return the MD5 hash of the name and the type.
16
26
  def attr_hash
17
27
  Digest::MD5.hexdigest("#{@name}:#{@ruby_type}")
18
28
  end
19
29
 
30
+ # An Attribute is equal to another if and only if its attr_hash value is the same.
20
31
  def ==(other)
21
32
  return false if other.class != self.class
22
33
  attr_hash == other.attr_hash
@@ -4,7 +4,9 @@ require 'optparse'
4
4
 
5
5
  module JSON2Ruby
6
6
 
7
+ # The CLI (Command Line Interface) functionality class for the json2ruby executable
7
8
  class CLI
9
+ # Run the json2ruby command, using arguments in ARGV.
8
10
  def self.run
9
11
 
10
12
  puts "json2ruby v#{VERSION}\n"
@@ -26,6 +28,7 @@ module JSON2Ruby
26
28
  write_files(rootclasses, writer, options)
27
29
  end
28
30
 
31
+ # Create the output directory with the options[:outputdir] if it does not exist.
29
32
  def self.ensure_output_dir(options)
30
33
  puts "Output Directory: #{options[:outputdir]}" if options[:verbose]
31
34
  unless Dir.exists?(options[:outputdir])
@@ -34,8 +37,8 @@ module JSON2Ruby
34
37
  end
35
38
  end
36
39
 
40
+ # Process ARGV for command line switches and return the options hash.
37
41
  def self.get_cli_options
38
-
39
42
  options = {}
40
43
  OptionParser.new do |opts|
41
44
  opts.banner = "Usage: #{$0} [options] <file.json> [<file.json>....]"
@@ -115,6 +118,7 @@ module JSON2Ruby
115
118
  options
116
119
  end
117
120
 
121
+ # Parse all JSON files in ARGV and build the Entity cache, using the supplied options Hash.
118
122
  def self.parse_files(options)
119
123
  # Reset the object cache
120
124
  Entity.reset_parse
@@ -137,6 +141,8 @@ module JSON2Ruby
137
141
  rootclasses
138
142
  end
139
143
 
144
+ # Write out all types in the Entity cache, except primitives and those contained in the
145
+ # rootclasses array, to the provided writer with the supplied options Hash.
140
146
  def self.write_files(rootclasses, writer, options)
141
147
  files = 0
142
148
  Entity.entities.each do |k,v|
@@ -171,6 +177,7 @@ module JSON2Ruby
171
177
  puts "Done, Generated #{files} file#{files==1 ? '' : 's'}"
172
178
  end
173
179
 
180
+ # Display the Entity supplied in ent with the supplied hash value hsh to STDOUT
174
181
  def self.display_entity(hsh, ent)
175
182
  puts "- #{ent.name} (#{ent.class.short_name} - #{hsh})"
176
183
  if ent.is_a?(Entity)
@@ -1,18 +1,31 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  module JSON2Ruby
4
+ # Collection represents a JSON Array
4
5
  class Collection
5
- attr_accessor :name, :original_name, :ruby_types
6
+ # The String name of the Array, i.e. the field name in which it was first encountered.
7
+ attr_accessor :name
8
+ # The original String name of the Array in the JSON ([^A-Za-z0-9_] are replaced with '_')
9
+ attr_accessor :original_name
10
+ # The array of types (Entity, Collection or Primitive instances) encountered in the JSON Array
11
+ attr_accessor :ruby_types
6
12
 
13
+ # The short name is 'Collection'
7
14
  def self.short_name
8
15
  "Collection"
9
16
  end
10
17
 
18
+ # Create a new Collection with the specified name and optional Array of ypes.
11
19
  def initialize(name, ruby_types = {})
12
20
  @name = name
13
21
  @ruby_types = ruby_types
14
22
  end
15
23
 
24
+ # Create a new, or return an existing, Collection named name that supports all types in obj_array.
25
+ # Optionally, options can be supplied:
26
+ # * :forcenumeric => true - Use RUBYNUMERIC instead of RUBYINTEGER / RUBYFLOAT.
27
+ #
28
+ # Note: Contained JSON Objects and Arrays will be recursively parsed into Entity and Collection instances.
16
29
  def self.parse_from(name, obj_array, options = {})
17
30
  ob = self.new(name)
18
31
  obj_array.each do |v|
@@ -41,6 +54,8 @@ module JSON2Ruby
41
54
  ob
42
55
  end
43
56
 
57
+ # Return a 128-bit hash as a hex string, representative of the set of possible types in the Collection
58
+ # Internally, this is calculated as the MD5 hash of the attr_hash values of all types.
44
59
  def attr_hash
45
60
  md5 = Digest::MD5.new
46
61
  @ruby_types.each do |k,typ|
@@ -49,11 +64,13 @@ module JSON2Ruby
49
64
  md5.hexdigest
50
65
  end
51
66
 
67
+ # Compare this Collection with another Collection. Two collections are equal if and only if they can contain exactly the same types.
52
68
  def ==(other)
53
69
  return false if other.class != self.class
54
70
  attr_hash == other.attr_hash
55
71
  end
56
72
 
73
+ # Generate a String comment of the form '<x>[] (<y)' where <x> and <y> are the name and original name of the Collection respectively.
57
74
  def comment
58
75
  x = "#{@name}[]"
59
76
  x += " (#{@original_name})" unless @original_name.nil?
@@ -1,19 +1,28 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  module JSON2Ruby
4
-
4
+ # Entity represents a JSON Object.
5
5
  class Entity
6
- attr_accessor :name, :original_name, :attributes
6
+ # The String name of the Object - i.e. the field name in which it was first encountered.
7
+ attr_accessor :name
8
+ # The original String name of the object in the JSON ([^A-Za-z0-9_] are replaced with '_')
9
+ attr_accessor :original_name
10
+ # A Hash of String names to Attribute instances for this Entity, representing its attributes.
11
+ attr_accessor :attributes
7
12
 
13
+ # The short name is 'Entity'
8
14
  def self.short_name
9
15
  "Entity"
10
16
  end
11
17
 
18
+ # Create a new Entity with the specified name and optional Hash of attributes (String name to Entity, Collection or Primitive instances)
12
19
  def initialize(name, attributes = {})
13
20
  @name = name
14
21
  @attributes = attributes
15
22
  end
16
23
 
24
+ # Return a 128-bit hash as a hex string, representative of the unique set of fields and their types, including all subobjects.
25
+ # Internally, this is calculated as the MD5 of all field names and their type attr_hash calls.
17
26
  def attr_hash
18
27
  md5 = Digest::MD5.new
19
28
  @attributes.each do |k,v|
@@ -22,11 +31,17 @@ module JSON2Ruby
22
31
  md5.hexdigest
23
32
  end
24
33
 
34
+ # Compare this Entity with another. An entity is equal to another entity if and only if it has:
35
+ # * The same number of fields
36
+ # * The fields have the same case-sensitive name
37
+ # * The fields have the same types, as tested with `attr_hash`
38
+ # i.e. in short, an entity is equal to another entity if and only if both +attr_hash+ calls return the same value.
25
39
  def ==(other)
26
40
  return false if other.class != self.class
27
41
  attr_hash == other.attr_hash
28
42
  end
29
43
 
44
+ # Reset the internal type cache for all Entities everywhere, and reset the global Unknown number.
30
45
  def self.reset_parse
31
46
  @@objs = {
32
47
  RUBYSTRING.attr_hash => RUBYSTRING,
@@ -38,6 +53,11 @@ module JSON2Ruby
38
53
  @@unknowncount = 0
39
54
  end
40
55
 
56
+ # Create a new, or return an existing, Entity named name that supports all fields in obj_hash.
57
+ # Optionally, options can be supplied:
58
+ # * :forcenumeric => true - Use RUBYNUMERIC instead of RUBYINTEGER / RUBYFLOAT.
59
+ #
60
+ # Note: Contained JSON Objects and Arrays will be recursively parsed into Entity and Collection instances.
41
61
  def self.parse_from(name, obj_hash, options = {})
42
62
  ob = self.new(name)
43
63
  obj_hash.each do |k,v|
@@ -70,16 +90,20 @@ module JSON2Ruby
70
90
  ob
71
91
  end
72
92
 
93
+ # Return the type cache of all Entity objects.
94
+ # This is a Hash of +hash_attr+ values to +Entity+ instances.
73
95
  def self.entities
74
96
  @@objs
75
97
  end
76
98
 
99
+ # Return a string of the form 'Unknown<x>' where <x> is a globally unique sequence.
77
100
  def self.get_next_unknown
78
101
  @@unknowncount ||= 0
79
102
  @@unknowncount += 1
80
103
  "Unknown#{@@unknowncount}"
81
104
  end
82
105
 
106
+ # Return a string of the form ' (<y>)' where <y> is the original_name of the Entity
83
107
  def comment
84
108
  x = @name
85
109
  x += " (#{@original_name})" unless @original_name.nil?
@@ -1,21 +1,30 @@
1
1
  module JSON2Ruby
2
-
2
+ # Represents a JSON Primitive. You should not instantiate this class - use the static instances:
3
+ # * JSON2Ruby::RUBYSTRING for JSON Strings
4
+ # * JSON2Ruby::RUBYINTEGER for JSON Integers
5
+ # * JSON2Ruby::RUBYFLOAT for JSON Floats
6
+ # * JSON2Ruby::RUBYBOOLEAN for JSON Booleans
7
+ # * JSON2Ruby::RUBYNUMERIC for JSON Numerics (Integers or floats)
3
8
  class Primitive
4
- attr_accessor :name, :original_name, :attr_hash
9
+ # The +String+ name of the Primitive.
10
+ attr_accessor :name
11
+ # +String+ Exists for compatibility.
12
+ attr_accessor :original_name
13
+ # The static +attr_hash+ of the Primitive.
14
+ attr_accessor :attr_hash
5
15
 
16
+ # The short name is 'Primitive'
6
17
  def self.short_name
7
18
  "Primitive"
8
19
  end
9
20
 
21
+ # Create a new Primitive with the specified +name+ and +attr_hash+
10
22
  def initialize(name, attr_hash)
11
23
  @name = name
12
24
  @attr_hash = attr_hash
13
25
  end
14
26
 
15
- def attr_hash
16
- @attr_hash
17
- end
18
-
27
+ # Return the +name+ of the Primitive
19
28
  def comment
20
29
  @name
21
30
  end
@@ -30,5 +39,5 @@ module JSON2Ruby
30
39
  # Primitive Representing a Ruby Boolean
31
40
  RUBYBOOLEAN = Primitive.new("Boolean","0123456789ABCDEF0123456789ABCDE2")
32
41
  # Psuedo-Primitive Representing a Numeric
33
- RUBYNUMERIC = Primitive.new("Numeric","0123456789ABCDEF0123456789ABCDE2")
42
+ RUBYNUMERIC = Primitive.new("Numeric","0123456789ABCDEF0123456789ABCDE3")
34
43
  end
@@ -3,7 +3,16 @@ require 'json'
3
3
  require 'optparse'
4
4
 
5
5
  module JSON2Ruby
6
+ # The RubyWriter class contains methods to output ruby code from a given Entity.
6
7
  class RubyWriter
8
+ # Return a String containing a Ruby class/module definition for the given Entity.
9
+ # Optionally, supply indent to set the indent of the generated code in spaces,
10
+ # and supply a Hash of options as follows:
11
+ # * :modules - Boolean if true, generate Ruby +module+ files instead of classes.
12
+ # * :require - Array of String items, each of which will generate a `require '<x>'` statement for each item
13
+ # * :superclass_name - String, if supplied, the superclass of the class to geneerate
14
+ # * :extend - Array of String items, each of which will generate a `extend '<x>'` statement for each item in the class
15
+ # * :include - Array of String items, each of which will generate a `include '<x>'` statement for each item in the class
7
16
  def self.to_code(entity, indent = 0, options = {})
8
17
  x = ""
9
18
  if options.has_key?(:require)
@@ -27,7 +36,14 @@ module JSON2Ruby
27
36
  x
28
37
  end
29
38
 
30
- def self.attributes_to_ruby(entity, indent, options = {})
39
+ # Return a String containing the Ruby code for each Attribute definition for in the supplied Entity.
40
+ # Optionally, supply indent to set the indent of the generated code in spaces,
41
+ # and supply a Hash of options as follows:
42
+ # * :attributemethod - String, the method to call to define attributes
43
+ # * :collectionmethod - String, the method to call to define collections
44
+ # * :includetypes - Boolean if true, include the string of the Attribute type as a second parameter to the definition call.
45
+ # * :namespace - String, the namespace of the type classes in the format 'Module::SubModule'...
46
+ def self.attributes_to_ruby(entity, indent = 0, options = {})
31
47
  ident = (' '*indent)
32
48
  x = ""
33
49
  entity.attributes.each do |k,v|
@@ -1,3 +1,5 @@
1
+ # The JSON2Ruby module encapsulates all classes and constants for the json2ruby gem and executable.
1
2
  module JSON2Ruby
2
- VERSION = '0.1.0'
3
+ # The Version of this json2ruby
4
+ VERSION = '0.1.1'
3
5
  end
@@ -62,8 +62,8 @@ describe JSON2Ruby::Collection do
62
62
 
63
63
  expect(col).to be_a(JSON2Ruby::Collection)
64
64
  expect(col.name).to eq("Test")
65
- expect(col.ruby_types.length).to eq(4)
66
- expect(col.attr_hash).to eq("e38d96234bfbf21545ed4ab2128b9ab4")
65
+ expect(col.ruby_types.length).to eq(5)
66
+ expect(col.attr_hash).to eq("94db8ab7a9379e835f6a69714fbec9cc")
67
67
  end
68
68
  end
69
69
 
@@ -59,7 +59,7 @@ describe JSON2Ruby::Entity do
59
59
  expect(ent).to be_a(JSON2Ruby::Entity)
60
60
  expect(ent.name).to eq("Test")
61
61
  expect(ent.attributes.length).to eq(6)
62
- expect(ent.attr_hash).to eq("592884f7d98c4a31b7d641b10636d546")
62
+ expect(ent.attr_hash).to eq("5681e2da2b9aa0a343e622ef771c0abb")
63
63
  end
64
64
  end
65
65
 
@@ -45,7 +45,7 @@ describe JSON2Ruby::Primitive do
45
45
  expect(JSON2Ruby::RUBYBOOLEAN.attr_hash).to eq('0123456789ABCDEF0123456789ABCDE2')
46
46
 
47
47
  expect(JSON2Ruby::RUBYNUMERIC.name).to eq('Numeric')
48
- expect(JSON2Ruby::RUBYNUMERIC.attr_hash).to eq('0123456789ABCDEF0123456789ABCDE2')
48
+ expect(JSON2Ruby::RUBYNUMERIC.attr_hash).to eq('0123456789ABCDEF0123456789ABCDE3')
49
49
  end
50
50
  end
51
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json2ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-21 00:00:00.000000000 Z
12
+ date: 2015-08-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: coveralls
@@ -223,3 +223,4 @@ test_files:
223
223
  - spec/primitive_spec.rb
224
224
  - spec/ruby_writer_spec.rb
225
225
  - spec/spec_helper.rb
226
+ has_rdoc: