dataset_explorer 0.1.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 788e4dd9aa7ed70db9482c9eb8c5cc35fabae5039232dc2c10e0276fa97caf14
4
- data.tar.gz: 0d14ebb6e7ae2363dfe47236b1a89565fbda381fecb4dc8732448dd27fbe82bf
3
+ metadata.gz: e0325eced24214509e9177b70341bc1120ea26c5b523918501f2884fdd57c92a
4
+ data.tar.gz: face9b64530c6b771258d23f512c24955e6bd073d881802d6b538dd0f5b046b7
5
5
  SHA512:
6
- metadata.gz: eae4397828a7fb6c88da601ed429292893a9925089e37c4b7be57d3879c664605bcdeb40736e27da2522c7a8e1fdd587d91419d59b22fb5912d4b96523a0b1f2
7
- data.tar.gz: c41ee84d680ce45f9d22e46b732bf31fc6490b0ded9f18f7ad721df4d91b9670747a83d375fcf78128e7e06e78993f93d5874870882d668940d37e02316d782d
6
+ metadata.gz: a1c7aa73cd0f51295b1cf01b1ece8e7756c9a5e498a22f475efccecb2036f065844f0564e9fd6c05379cefe35729ec7cdc84aea57577f81c46a17e3ab628586b
7
+ data.tar.gz: 0d75d122ea2a1696a06215c631e14760b1d6cba3271c73462af85ade96f85b886f72f6fb5a0500fd2794720a5c46509c2d2e4c14ca3e7ab632a00ec4863e6532
@@ -7,6 +7,7 @@ Metrics/BlockLength:
7
7
  - 'spec/**/*'
8
8
 
9
9
  Metrics/MethodLength:
10
+ Max: 15
10
11
  Exclude:
11
12
  - 'db/migrate/**.rb'
12
13
 
data/README.md CHANGED
@@ -56,82 +56,82 @@ urls = {
56
56
  COLLECTOR = DatasetExplorer::Collector.instance
57
57
 
58
58
  urls.each do |provider, url|
59
- data = [JSON.parse(open(url).read)].flatten
60
-
61
- data.each do |item|
62
- COLLECTOR.collect(provider, item)
63
- end
59
+ data = JSON.parse(open(url).read)
60
+ COLLECTOR.collect(provider, data)
64
61
  end
65
62
 
66
- explanation = COLLECTOR.explain_all
63
+ COLLECTOR.explain_all(format: :table).each do |type, explanation|
64
+ puts type
65
+ puts explanation
66
+ end
67
67
  ```
68
68
 
69
69
  Explanation will be:
70
70
 
71
- ```ruby
72
- {
73
- github: [
74
- "jekyll",
75
- "jekyll-sass-converter",
76
- "kramdown",
77
- "jekyll-commonmark-ghpages",
78
- "liquid",
79
- "rouge",
80
- "github-pages-health-check",
81
- "jekyll-redirect-from",
82
- "jekyll-sitemap",
83
- "jekyll-feed",
84
- "jekyll-gist",
85
- "jekyll-paginate",
86
- "jekyll-coffeescript",
87
- "jekyll-seo-tag",
88
- "jekyll-github-metadata",
89
- "jekyll-avatar",
90
- "jekyll-remote-theme",
91
- "jemoji",
92
- "jekyll-mentions",
93
- "jekyll-relative-links",
94
- "jekyll-optional-front-matter",
95
- "jekyll-readme-index",
96
- "jekyll-default-layout",
97
- "jekyll-titles-from-headings",
98
- "jekyll-swiss",
99
- "minima",
100
- "jekyll-theme-primer",
101
- "jekyll-theme-architect",
102
- "jekyll-theme-cayman",
103
- "jekyll-theme-dinky",
104
- "jekyll-theme-hacker",
105
- "jekyll-theme-leap-day",
106
- "jekyll-theme-merlot",
107
- "jekyll-theme-midnight",
108
- "jekyll-theme-minimal",
109
- "jekyll-theme-modernist",
110
- "jekyll-theme-slate",
111
- "jekyll-theme-tactile",
112
- "jekyll-theme-time-machine",
113
- "ruby",
114
- "github-pages",
115
- "html-pipeline",
116
- "sass",
117
- "safe_yaml",
118
- "nokogiri",
119
- ],
120
- github_repo: [
121
- "name",
122
- "path",
123
- "sha",
124
- "size",
125
- "url",
126
- "html_url",
127
- "git_url",
128
- "download_url",
129
- "type",
130
- "_links.self",
131
- "_links.git",
132
- "_links.html"
133
- ]
134
- }
71
+ ```
72
+ github
73
+ +------------------------------+--------------------------------------------------------------------------+
74
+ | jekyll | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
75
+ | jekyll-sass-converter | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
76
+ | kramdown | Possible types: [string], NULL, Min/max Length: 6/6 |
77
+ | jekyll-commonmark-ghpages | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
78
+ | liquid | Possible types: [string], NULL, Min/max Length: 5/5 |
79
+ | rouge | Possible types: [string], NULL, Min/max Length: 6/6 |
80
+ | github-pages-health-check | Possible types: [string], NULL, Min/max Length: 6/6 |
81
+ | jekyll-redirect-from | Possible types: [string], NULL, Min/max Length: 6/6 |
82
+ | jekyll-sitemap | Possible types: [string], NULL, Min/max Length: 5/5 |
83
+ | jekyll-feed | Possible types: [string], NULL, Min/max Length: 6/6 |
84
+ | jekyll-gist | Possible types: [string], NULL, Min/max Length: 5/5 |
85
+ | jekyll-paginate | Possible types: [string], NULL, Min/max Length: 5/5 |
86
+ | jekyll-coffeescript | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
87
+ | jekyll-seo-tag | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
88
+ | jekyll-github-metadata | Possible types: [string], NULL, Min/max Length: 6/6 |
89
+ | jekyll-avatar | Possible types: [string], NULL, Min/max Length: 5/5 |
90
+ | jekyll-remote-theme | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
91
+ | jemoji | Possible types: [date, time, string], NULL, Min/max Length: 6/6 |
92
+ | jekyll-mentions | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
93
+ | jekyll-relative-links | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
94
+ | jekyll-optional-front-matter | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
95
+ | jekyll-readme-index | Possible types: [string], NULL, Min/max Length: 5/5 |
96
+ | jekyll-default-layout | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
97
+ | jekyll-titles-from-headings | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
98
+ | jekyll-swiss | Possible types: [string], NULL, Min/max Length: 5/5 |
99
+ | minima | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
100
+ | jekyll-theme-primer | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
101
+ | jekyll-theme-architect | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
102
+ | jekyll-theme-cayman | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
103
+ | jekyll-theme-dinky | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
104
+ | jekyll-theme-hacker | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
105
+ | jekyll-theme-leap-day | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
106
+ | jekyll-theme-merlot | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
107
+ | jekyll-theme-midnight | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
108
+ | jekyll-theme-minimal | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
109
+ | jekyll-theme-modernist | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
110
+ | jekyll-theme-slate | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
111
+ | jekyll-theme-tactile | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
112
+ | jekyll-theme-time-machine | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
113
+ | ruby | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
114
+ | github-pages | Possible types: [date, time, string, integer], NULL, Min/max Length: 3/3 |
115
+ | html-pipeline | Possible types: [date, time, string], NULL, Min/max Length: 6/6 |
116
+ | sass | Possible types: [date, time, string], NULL, Min/max Length: 5/5 |
117
+ | safe_yaml | Possible types: [string], NULL, Min/max Length: 5/5 |
118
+ | nokogiri | Possible types: [date, time, string], NULL, Min/max Length: 6/6 |
119
+ +------------------------------+--------------------------------------------------------------------------+
120
+ github_repo_contents
121
+ +-----------------+---------------------------------------------------------+
122
+ | [].name | Possible types: [string], NULL, Min/max Length: 2/14 |
123
+ | [].path | Possible types: [string], NULL, Min/max Length: 2/14 |
124
+ | [].sha | Possible types: [string], NULL, Min/max Length: 40/40 |
125
+ | [].size | Possible types: [integer], NULL |
126
+ | [].url | Possible types: [string], NULL, Min/max Length: 75/87 |
127
+ | [].html_url | Possible types: [string], NULL, Min/max Length: 57/69 |
128
+ | [].git_url | Possible types: [string], NULL, Min/max Length: 103/103 |
129
+ | [].download_url | Possible types: [string], NULL, Min/max Length: 72/79 |
130
+ | [].type | Possible types: [string], NULL, Min/max Length: 3/4 |
131
+ | []._links.self | Possible types: [string], NULL, Min/max Length: 75/87 |
132
+ | []._links.git | Possible types: [string], NULL, Min/max Length: 103/103 |
133
+ | []._links.html | Possible types: [string], NULL, Min/max Length: 57/69 |
134
+ +-----------------+---------------------------------------------------------+
135
135
  ```
136
136
 
137
137
  Or if you try like this
@@ -155,7 +155,7 @@ data = {
155
155
  }
156
156
 
157
157
  DatasetExplorer::Collector.instance.collect(:achievements, data)
158
- result = DatasetExplorer::Collector.explain_all(:achievements)
158
+ result = DatasetExplorer::Collector.instance.explain(:achievements).keys
159
159
 
160
160
  # result is:
161
161
 
@@ -28,4 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.bindir = 'exe'
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ['lib']
31
+
32
+ spec.add_dependency 'terminal-table'
31
33
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dataset_explorer/version'
4
+ require 'dataset_explorer/value_evaluator'
4
5
  require 'dataset_explorer/item_collector'
5
6
  require 'dataset_explorer/collector'
6
7
 
@@ -14,14 +14,20 @@ module DatasetExplorer
14
14
  collector_for(type).add(item)
15
15
  end
16
16
 
17
- def explain_all
17
+ def explain_all(format: :hash)
18
18
  @collectors.keys.map do |key|
19
- [key, explain(key)]
19
+ [key, explain(key, format: format)]
20
20
  end.to_h
21
21
  end
22
22
 
23
- def explain(type)
24
- @collectors.fetch(type).values
23
+ def explain(type, format: :hash)
24
+ explanation = @collectors.fetch(type).explain
25
+
26
+ if format == :table
27
+ explanation = to_table(explanation)
28
+ end
29
+
30
+ explanation
25
31
  end
26
32
 
27
33
  private
@@ -30,6 +36,14 @@ module DatasetExplorer
30
36
  @collectors[type] ||= ItemCollector.new
31
37
  end
32
38
 
39
+ def to_table(fields)
40
+ rows = []
41
+ fields.each do |key, description|
42
+ rows << [key, description]
43
+ end
44
+ Terminal::Table.new(rows: rows)
45
+ end
46
+
33
47
  private_class_method :new
34
48
  end
35
49
  end
@@ -3,10 +3,19 @@
3
3
  module DatasetExplorer
4
4
  class ItemCollector
5
5
  def initialize
6
- @values = []
6
+ @keys = []
7
+ @evaluators = {}
7
8
  end
8
9
 
9
- attr_reader :values
10
+ def explain
11
+ {}.tap do |explanation|
12
+ @evaluators.each do |field, evaluator|
13
+ explanation[field] = evaluator.describe
14
+ end
15
+ end
16
+ end
17
+
18
+ attr_reader :keys
10
19
 
11
20
  def add(item)
12
21
  unless item.is_a?(Array)
@@ -25,15 +34,17 @@ module DatasetExplorer
25
34
  map_keys(item[key], key, prefix)
26
35
  end.flatten.map(&:to_s).uniq
27
36
 
28
- @values << new_values
29
- @values = @values.flatten.uniq
37
+ @keys << new_values
38
+ @keys = @keys.flatten.uniq
30
39
  end
31
40
 
32
41
  # rubocop:disable Metrics/MethodLength
42
+ # rubocop:disable Metrics/AbcSize
33
43
  def map_keys(value, key = nil, prefix = nil)
34
44
  prefix = [prefix, key].compact.join('.')
35
45
 
36
46
  unless mappable?(value)
47
+ evaluator_for(prefix).evaluate(value)
37
48
  return prefix
38
49
  end
39
50
 
@@ -45,9 +56,9 @@ module DatasetExplorer
45
56
 
46
57
  if value.respond_to?(:each)
47
58
  prefix = "#{prefix}.[]"
48
- return [].tap do |values|
59
+ return [].tap do |keys|
49
60
  value.each do |item_value|
50
- values << map_keys(item_value, nil, prefix)
61
+ keys << map_keys(item_value, nil, prefix)
51
62
  end
52
63
  end
53
64
  end
@@ -55,6 +66,7 @@ module DatasetExplorer
55
66
  raise Error, 'Unforseen scenario'
56
67
  end
57
68
  # rubocop:enable Metrics/MethodLength
69
+ # rubocop:enable Metrics/AbcSize
58
70
 
59
71
  def mappable?(value)
60
72
  if behaves_like_hash?(value)
@@ -75,5 +87,9 @@ module DatasetExplorer
75
87
  def behaves_like_array?(value)
76
88
  value.respond_to?(:each)
77
89
  end
90
+
91
+ def evaluator_for(field)
92
+ @evaluators[field.to_s] ||= ValueEvaluator.new(field)
93
+ end
78
94
  end
79
95
  end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'time'
5
+ require 'terminal-table'
6
+
7
+ module DatasetExplorer
8
+ class ValueEvaluator
9
+ attr_reader :min_length
10
+ attr_reader :max_length
11
+
12
+ def initialize(field_name)
13
+ @field_name = field_name
14
+ @null = true
15
+ @evaluators = {
16
+ 'date' => DateEvaluator.new,
17
+ 'time' => TimeEvaluator.new,
18
+ 'string' => StringEvaluator.new,
19
+ 'float' => FloatEvaluator.new,
20
+ 'integer' => IntegerEvaluator.new,
21
+ 'boolean' => BooleanEvaluator.new
22
+ }
23
+ @min_length = nil
24
+ @max_length = nil
25
+ end
26
+
27
+ def evaluate(value)
28
+ if value.nil?
29
+ @null = true
30
+ return
31
+ end
32
+
33
+ evaluate_length(value)
34
+
35
+ @evaluators.each do |key, evaluator|
36
+ unless evaluator.accept?(value)
37
+ @evaluators.delete(key)
38
+ end
39
+ end
40
+ end
41
+
42
+ def types
43
+ @evaluators.keys
44
+ end
45
+
46
+ def describe
47
+ parts = ["Possible types: [#{types.join(', ')}]"]
48
+ if @null
49
+ parts << 'NULL'
50
+ end
51
+
52
+ if min_length
53
+ parts << "Min/max Length: #{min_length}/#{max_length}"
54
+ end
55
+
56
+ parts.join(', ')
57
+ end
58
+
59
+ def evaluate_length(value)
60
+ unless value.respond_to?(:length)
61
+ return
62
+ end
63
+
64
+ length = value.length
65
+ @min_length ||= length
66
+ @max_length ||= length
67
+
68
+ if @min_length > length
69
+ @min_length = length
70
+ end
71
+
72
+ if @max_length < length
73
+ @max_length = length
74
+ end
75
+ end
76
+
77
+ class TimeEvaluator
78
+ def accept?(value)
79
+ if value.is_a?(String)
80
+ return Time.parse(value.to_s)
81
+ end
82
+
83
+ value.is_a?(Time)
84
+ rescue ArgumentError
85
+ false
86
+ end
87
+ end
88
+
89
+ class DateEvaluator
90
+ def accept?(value)
91
+ if value.is_a?(String)
92
+ return Date.parse(value.to_s)
93
+ end
94
+
95
+ value.is_a?(Date)
96
+ rescue ArgumentError
97
+ false
98
+ end
99
+ end
100
+
101
+ class StringEvaluator
102
+ def accept?(value)
103
+ value.is_a?(String)
104
+ end
105
+ end
106
+
107
+ class FloatEvaluator
108
+ def accept?(value)
109
+ Float(value).to_s == value.to_s
110
+ rescue ArgumentError, TypeError
111
+ false
112
+ end
113
+ end
114
+
115
+ class IntegerEvaluator
116
+ def accept?(value)
117
+ Integer(value)
118
+ rescue ArgumentError, TypeError
119
+ false
120
+ end
121
+ end
122
+
123
+ class BooleanEvaluator
124
+ ACCEPT = %w[
125
+ true
126
+ false
127
+ ].freeze
128
+
129
+ def accept?(value)
130
+ ACCEPT.include?(value.to_s.downcase)
131
+ end
132
+ end
133
+ end
134
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatasetExplorer
4
- VERSION = '0.1.1'
4
+ VERSION = '1.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dataset_explorer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcelo Jacobus
@@ -9,7 +9,21 @@ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
11
  date: 2020-05-25 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: terminal-table
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: Explore and maps fields from a dataset - I.E. Api response
14
28
  email:
15
29
  - marcelo.jacobus@gmail.com
@@ -32,6 +46,7 @@ files:
32
46
  - lib/dataset_explorer.rb
33
47
  - lib/dataset_explorer/collector.rb
34
48
  - lib/dataset_explorer/item_collector.rb
49
+ - lib/dataset_explorer/value_evaluator.rb
35
50
  - lib/dataset_explorer/version.rb
36
51
  homepage: https://github.com/mjacobus/dataset_explorer
37
52
  licenses: