data_list_converter 0.3.9 → 0.4.3

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
- SHA1:
3
- metadata.gz: 2ecbbb8c5d6e3ad1e2de6f3b4a8fc5033cdc83ff
4
- data.tar.gz: f4b8eb65bf43e3f28ed3607b06f5643eb278b4a4
2
+ SHA256:
3
+ metadata.gz: ed694a5c72e52682133a22004d381f3968c3d28db54cbeba194eda7c793e70a9
4
+ data.tar.gz: 656daa9eb323ffa7b7bddb8e40df86606889f091f56c47069f39e37c9f434741
5
5
  SHA512:
6
- metadata.gz: ea3669bc7a3bb7e381387538433bad76401ffe288d3dd54d2d7181797719951b138db9810fc98ac1460361fa3b25b6924d040c06f3cb19bb54db4bc43545b718
7
- data.tar.gz: 159e246ba2bc8e83b0b699d4a503328bd2ddd2d5792cabaea6c541388f705d0d41a62b3c06fd09a1e6aceac3d1d7fb4632798a847d273fc2ab9c963524d44601
6
+ metadata.gz: ad413ccb9e7f0552a39965c69f7924df825eda9933d9acfb83e20455ea03cdd25f34dd8275187190ca868b34fa490c4025c1024820ebf8627345b7e1d6a8d969
7
+ data.tar.gz: be36997b5d5b37af61e8c5281038ecb8187650ee3d8c506ea852fec5bba8c324a8434e53fe2e2ba729a86deb667376d331aed6194c9cd05286fd636cdbc48219
data/README.md CHANGED
@@ -22,61 +22,73 @@ DataListConverter.convert(:xls_file, :multi_sheet_item_data, {filename: 'result.
22
22
  You can also add filter to this process:
23
23
 
24
24
  ```ruby
25
- filters = [
26
- # filter with default options
27
- :limit,
28
- # filter with options
29
- {limit: {size: 2}},
30
- # multiple filters
31
- [{limit: {size: 12}},
32
- {count: {size: 4}}],
33
- ]
34
- filters.map do |filter|
35
- data = [{name: "james"}] * 10
36
- DataListConverter.convert(:item_data, :table_data, data, table_iterator: {filter: filter})
37
- end
25
+ data = (1..20).map{|i| {name: "user-#{i}", age: i+20}}
26
+ # filter with default options (limit 10)
27
+ DataListConverter.convert(:item_data, :table_data, data, item_iterator: {filter: :limit})
28
+ # filter with options
29
+ DataListConverter.convert(:item_data, :table_data, data, item_iterator: {filter: {limit: {size: 2}}})
30
+ # multiple filters
31
+ DataListConverter.convert(:item_data, :table_data, data, item_iterator: {filter: [{limit: {size: 12}}, {count: {size: 4}}]})
38
32
  ```
39
33
 
40
- Please read [the source code](https://github.com/halida/data_list_converter/blob/master/lib/data_list_converter/) for more information,
41
- also you can check [test examples](https://github.com/halida/data_list_converter/blob/master/test/).
42
-
43
34
  ## Data Types
44
35
 
36
+ Default data types:
37
+
45
38
  - **item_data** like: `[{name: 'James', age: '22'}, ...]`, keys should be symbol.
46
39
  - **item_iterator** iterator for item_data, used like: iter.call{|item| out << item}
47
40
  - **table_data** like: `[["name", "age"], ["James", "22"], ["Bob", "33"], ...]`
48
41
  - **table_iterator** iterator for table_data
49
- - **csv_file** file in csv format
50
- - **xls_file** file in excel format, should install `spreadsheet` gem, and `require 'data_list_converter/types/xls_file'`
51
- - **xlsx_file** file in excel xml format, should install `rubyXL` gem, and `require 'data_list_converter/types/xlsx_file'`
52
42
  - **multi_sheet** Contains several data with sheets:
53
43
  - **multi_sheet_table_iterator**: like: `{sheet1: table_iterator1, sheet2: table_iterator2}`
54
44
  - **multi_sheet_table_data**: like: `{sheet1: [['name', 'age'], ...], sheet2: ...}`
55
45
  - **multi_sheet_item_iterator**: like: `{sheet1: item_iterator1, sheet2: item_iterator2}`
56
46
  - **multi_sheet_item_data**: like: `{sheet1: [{name: 'James', age: 32}], sheet2: ...}`
57
- - **records** ActiveRecord records, usage: `DataListConverter.convert(:records, :item_data, Users.where(condition), item_iterator: {columns: [:name, :age]})`
58
47
 
48
+ Plugin data types, should required first by `require 'data_list_converter/types/#{type}'`
49
+
50
+ - **csv_file** file in csv format
51
+ - **xls_file** file in excel format, should install `spreadsheet` gem first
52
+ - **xlsx_file** file in excel xml format, should install `rubyXL` gem first
53
+ - **records** ActiveRecord records
54
+
55
+ Please check [test examples](https://github.com/halida/data_list_converter/blob/master/test/types_test.rb) to see how to use those types.
59
56
 
60
57
  ## Filters
61
58
 
62
- **item_iterator/table_iterator limit**: limit item_iterator result counts, usage: `DataListConverter.convert(:item_data, :table_data, item_data, item_iterator: {filter: {limit: {size: 2}}})`
59
+ **item_iterator/table_iterator limit**: limit item_iterator result counts, usage: `DataListConverter.convert(:item_data, :table_data, item_data, item_iterator: {filter: {limit: {size: 2}}})`, default limit size is 10.
63
60
 
64
- **item_iterator count**: count item_iterator items, usage: `DataListConverter.convert(:xls_file, :item_data, {filename: 'result.xls'}, item_iterator: {filter: {count: {size: 10}}})`, it will print current item counts every `size`.
61
+ **item_iterator count**: count item_iterator items, usage: `DataListConverter.convert(:xls_file, :item_data, {filename: 'result.xls'}, item_iterator: {filter: {count: {size: 10}}})`, it will print current item counts every `size`, please [see here](https://github.com/halida/data_list_converter/blob/master/lib/data_list_converter/filters/count.rb) for more options.
65
62
 
66
- Please check more [test examples](https://github.com/halida/data_list_converter/blob/master/test/filters_test.rb)
63
+ Please see [test examples](https://github.com/halida/data_list_converter/blob/master/test/filters_test.rb) to learn how to use filter.
64
+
65
+ ## helpers
66
+
67
+ - **types**: Get current valid types.
68
+ - **routes**: Get current valid routes.
69
+ - **file_types**: Get current file types, which is the types has `_file` suffix.
70
+ - **get_file_format**: Get file type by filename, which compare file extension with `file_types`. `DataListConverter.get_file_format('xxx.xls') == :xls_file`
71
+ - **save_to_file**: Save data to file, it will use `get_file_format` to find proper file format. `DataListConverter.save_to_file(filename, data, data_format=:item_data)`
72
+ - **load_from_file**: Get data from file, it will use `get_file_format` to find proper file format. `DataListConverter.load_from_file(filename, data_format=:item_data)`
73
+ - **unify_item_data_keys**: Sometimes in the `item_data` list, each data keys don't exactly same, so use this function to fix it, example: `DataListConverter.unify_item_data_keys([{a: 12}, {b: 11}]) == [{a: 12, b: nil}, {a: nil, b: 11}]`.
74
+ - **flatten**: Flatten multi level item_data list into one level, example: `DataListConverter.flatten({a: {b: 12}, c: {d: {e: 11}}}) == {:"a:b"=>12, :"c:d:e"=>11}`, can change seperator: `DataListConverter.flatten(data, '_')`, set max level: `DataListConverter.flatten(data, '_', 2)`
67
75
 
68
76
  ## Extend
69
77
 
70
78
  You can add your own data types and filters, example:
71
79
 
72
80
  ```ruby
73
- DataListConverter.register_converter(:records, :item_iterator) do |records, options|
74
- columns = options[:columns]
81
+ DataListConverter.register_converter(:records, :item_iterator) do |input, options|
82
+ query = self.parameter(input, :query, :input)
83
+ columns = self.parameter(input, :columns, :input)
84
+ display = input[:display] || columns
85
+
75
86
  lambda { |&block|
76
- records.find_each do |record|
77
- item = columns.map do |column|
78
- [column.first.to_sym, record.send(column[1])]
79
- end.to_h
87
+ query.pluck(*columns).each do |data|
88
+ item = {}
89
+ data.each_with_index do |d, i|
90
+ item[display[i]] = d
91
+ end
80
92
  block.call(item)
81
93
  end
82
94
  }
@@ -94,13 +106,3 @@ DataListConverter.register_filter(:item_iterator, :limit) do |proc, options|
94
106
  }
95
107
  end
96
108
  ```
97
-
98
-
99
- ## Todo
100
-
101
- - check type exists
102
- - register can bind method again
103
- - better API
104
- - better error message
105
- - load file/save file with auto format by extname
106
- - report error when cannot find type
@@ -1,3 +1,10 @@
1
+ ## 0.4
2
+
3
+ Add parameter check, type check, change record type API.
4
+
5
+ - 0.4.1 add max_level to flatten helper
6
+ - 0.4.2 fix value cannot save if value is symbol
7
+
1
8
  ## 0.3
2
9
 
3
10
  Refactor.
@@ -8,6 +15,7 @@ Refactor.
8
15
  - 0.3.7 add marshal_file type, and load_from_file, save_to_file helper
9
16
  - 0.3.8 add raw type
10
17
  - 0.3.9 add unify_item_data_keys helper
18
+ - 0.3.10 add flatten
11
19
 
12
20
  ## 0.2
13
21
 
@@ -17,6 +17,8 @@ Gem::Specification.new do |s|
17
17
  s.add_development_dependency 'spreadsheet', '~> 1.0'
18
18
  s.add_development_dependency 'rubyXL', '~> 3.3'
19
19
  s.add_development_dependency 'pry', '~> 0.10.1'
20
+ s.add_development_dependency 'sqlite3', '~> 1.3'
21
+ s.add_development_dependency 'activerecord', '~> 4.2'
20
22
 
21
23
  s.files = `git ls-files`.split("\n")
22
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -21,6 +21,7 @@ class DataListConverter
21
21
  puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}\t#{msg}"
22
22
  end
23
23
 
24
+ # register_converter(:item_data, :item_iterator){ |data, options| ... }
24
25
  def register_converter(from_type, to_type, &block)
25
26
  @route_map = nil # clear cache
26
27
  CONVERTERS[[from_type, to_type]] = block
@@ -44,7 +45,7 @@ class DataListConverter
44
45
  def convert(from_type, to_type, from_value, options={})
45
46
  methods = []
46
47
  add_filter = lambda { |type|
47
- filters = (options[type] || {}).delete(:filter)
48
+ filters = (options[type] || {})[:filter]
48
49
  return unless filters
49
50
  methods += normalize_filters(type, filters)
50
51
  }
@@ -57,6 +58,7 @@ class DataListConverter
57
58
  from_type, to_type = route[i], route[i+1]
58
59
  method = CONVERTERS[[from_type, to_type]]
59
60
  raise "cannot find converter #{from_type} -> #{to_type}" unless method
61
+ self.log "#{from_type} -> #{to_type} options: #{options[to_type]}"
60
62
  methods.push([method, options[to_type] || {}])
61
63
  add_filter.call(to_type)
62
64
  end
@@ -91,7 +93,11 @@ class DataListConverter
91
93
  # If we want to convert between types, like: convert item_data into csv_file,
92
94
  # we need find all the intermidate data type, like: [:item_data, :item_iterator, :table_iterator, :csv_file]
93
95
  def find_route(from_type, to_type)
96
+ [from_type, to_type].each do |type|
97
+ raise Exception, "cannot find type: #{type}" unless self.types.include?(type)
98
+ end
94
99
  raise Exception, "from_type should not equal to to_type: #{from_type}" if from_type == to_type
100
+
95
101
  # map wide search
96
102
  checked = Set.new
97
103
  checking = Set.new([from_type])
@@ -124,7 +130,10 @@ class DataListConverter
124
130
  checking += Set.new(next_nodes) - checked
125
131
  end
126
132
  end
127
- raise Exception, "Route not found: #{from_type} -> #{to_type}"
133
+
134
+ log = ["Route not found: #{from_type} -> #{to_type}", "Current routes:"]
135
+ log += self.routes.map{|from, to| "#{from} -> #{to}"}
136
+ raise Exception, log.join("\n")
128
137
  end
129
138
 
130
139
  # convert adjacency list into quick lookup hash
@@ -5,6 +5,7 @@ class DataListConverter
5
5
  msg_format = options[:msg] || "on %{count}"
6
6
  total_format = options[:total] || "total: %{total}"
7
7
  out = options[:out] || STDOUT
8
+
8
9
  total = 1
9
10
  lambda { |&block|
10
11
  proc.call do |item|
@@ -1,14 +1,14 @@
1
1
  class DataListConverter
2
- def self.save_to_file(filename, data, data_format=:item_data)
2
+ def self.save_to_file(filename, data, data_format=:item_data, options={})
3
3
  file_format = self.get_file_format(filename)
4
- DataListConverter.convert(data_format, file_format, data,
5
- file_format => {filename: filename})
4
+ options[file_format] = {filename: filename}
5
+ DataListConverter.convert(data_format, file_format, data, options)
6
6
  end
7
7
 
8
- def self.load_from_file(filename, data_format=:item_data)
8
+ def self.load_from_file(filename, data_format=:item_data, options={})
9
9
  file_format = self.get_file_format(filename)
10
- DataListConverter.convert(file_format, data_format,
11
- {filename: filename})
10
+ options[:filename] = filename
11
+ DataListConverter.convert(file_format, data_format, options)
12
12
  end
13
13
 
14
14
  def self.get_file_format(filename)
@@ -23,6 +23,10 @@ class DataListConverter
23
23
  CONVERTERS.keys.flatten.uniq.sort
24
24
  end
25
25
 
26
+ def self.routes
27
+ CONVERTERS.keys
28
+ end
29
+
26
30
  def self.file_types
27
31
  matcher = /(.*)_file$/
28
32
  DataListConverter.types.select do |type|
@@ -46,4 +50,32 @@ class DataListConverter
46
50
  end
47
51
  end
48
52
  end
53
+
54
+ # flatten multi level item data into one level, example:
55
+ # {a: {b: 12}, c: {d: {e: 11}}}
56
+ # =>
57
+ # {:"a:b"=>12, :"c:d:e"=>11}
58
+ def self.flatten(data, sep=':', max_level=nil)
59
+ out = {}
60
+ recursive_flatten(out, data, nil, sep, 1, max_level)
61
+ out
62
+ end
63
+
64
+ def self.recursive_flatten(out, data, header, sep, level, max_level)
65
+ data.each do |k, v|
66
+ k = header ? :"#{header}#{sep}#{k}" : k
67
+ if v.kind_of?(Hash) and (!max_level or level <= max_level)
68
+ recursive_flatten(out, v, k, sep, level+1, max_level)
69
+ else
70
+ out[k] = v
71
+ end
72
+ end
73
+ end
74
+
75
+ def self.parameter(data, key, type)
76
+ raise Exception, "`#{type}` should be hash, not `#{data.class}`: #{data}" unless data.kind_of?(Hash)
77
+ raise Exception, "Need `#{key}` for `#{type}`, current: #{data}" if not data.has_key?(key)
78
+ data.fetch(key)
79
+ end
80
+
49
81
  end
@@ -3,7 +3,8 @@ require 'csv'
3
3
  class DataListConverter
4
4
  self.register_converter(:csv_file, :table_iterator) do |input, options|
5
5
  lambda { |&block|
6
- CSV.open(input[:filename]) do |csv|
6
+ filename = self.parameter(input, :filename, :input)
7
+ CSV.open(filename) do |csv|
7
8
  csv.each do |row|
8
9
  block.call(row)
9
10
  end
@@ -12,7 +13,8 @@ class DataListConverter
12
13
  end
13
14
 
14
15
  self.register_converter(:table_iterator, :csv_file) do |proc, options|
15
- CSV.open(options[:filename], 'wb', force_quotes: true) do |csv|
16
+ filename = self.parameter(options, :filename, :csv_file)
17
+ CSV.open(filename, 'wb', force_quotes: true) do |csv|
16
18
  proc.call do |row|
17
19
  csv << row
18
20
  end
@@ -1,13 +1,15 @@
1
1
  class DataListConverter
2
2
 
3
3
  def self.marshal_file_to_data(input, options=nil)
4
- File.open(input[:filename]) do |f|
4
+ filename = self.parameter(input, :filename, :input)
5
+ File.open(filename) do |f|
5
6
  Marshal.load(f)
6
7
  end
7
8
  end
8
9
 
9
10
  def self.marshal_data_to_file(data, options)
10
- File.open(options[:filename], 'w+') do |f|
11
+ filename = self.parameter(options, :filename, :marshal)
12
+ File.open(filename, 'w+') do |f|
11
13
  Marshal.dump(data, f)
12
14
  end
13
15
  options[:filename]
@@ -19,8 +19,9 @@ class DataListConverter
19
19
  :"multi_sheet_#{from_type}",
20
20
  :"multi_sheet_#{to_type}",
21
21
  ) do |data, options|
22
+ self.log("multi_sheet #{from_type} -> #{to_type} with options: #{options}")
22
23
  data.map do |sheet, from_data|
23
- to_data = self.convert(from_type, to_type, from_data)
24
+ to_data = self.convert(from_type, to_type, from_data, options)
24
25
  [sheet, to_data]
25
26
  end.to_h
26
27
  end
@@ -1,13 +1,20 @@
1
1
  # ActiveRecords
2
2
  class DataListConverter
3
3
 
4
- self.register_converter(:records, :item_iterator) do |records, options|
5
- columns = options[:columns]
4
+ # columns = [:table_column1, :table_column2, ...]
5
+ # display = [:display_name1, :display_name2, ...]
6
+ # convert(:records, :item_data, query: query, columns: columns, display: display)
7
+ self.register_converter(:records, :item_iterator) do |input, options|
8
+ query = self.parameter(input, :query, :input)
9
+ columns = self.parameter(input, :columns, :input)
10
+ display = input[:display] || columns
11
+
6
12
  lambda { |&block|
7
- records.find_each do |record|
8
- item = columns.map do |column|
9
- [column[0].to_sym, record.send(column[1])]
10
- end.to_h
13
+ query.pluck(*columns).each do |data|
14
+ item = {}
15
+ data.each_with_index do |d, i|
16
+ item[display[i]] = d
17
+ end
11
18
  block.call(item)
12
19
  end
13
20
  }
@@ -5,7 +5,8 @@ class DataListConverter
5
5
 
6
6
  self.register_converter(:xls_file, :table_iterator) do |input, options|
7
7
  lambda { |&block|
8
- book = Spreadsheet.open(input[:filename])
8
+ filename = self.parameter(input, :filename, :input)
9
+ book = Spreadsheet.open(filename)
9
10
  sheet = book.worksheet input[:sheet] || 0
10
11
  sheet.each do |row|
11
12
  block.call(row.to_a)
@@ -18,11 +19,13 @@ class DataListConverter
18
19
  sheet = book.create_worksheet(name: (options[:sheet] || "Sheet1"))
19
20
  i = 0
20
21
  proc.call do |row|
22
+ row = row.map(&:to_s)
21
23
  sheet.row(i).push *row
22
24
  i += 1
23
25
  end
24
- book.write(options[:filename])
25
- options[:filename]
26
+ filename = self.parameter(options, :filename, :xls_file)
27
+ book.write(filename)
28
+ filename
26
29
  end
27
30
 
28
31
  self.register_converter(:multi_sheet_table_iterator, :xls_file) do |data, options|
@@ -31,17 +34,19 @@ class DataListConverter
31
34
  sheet = book.create_worksheet(name: name.to_s)
32
35
  i = 0
33
36
  table_iterator.call do |row|
37
+ row = row.map(&:to_s)
34
38
  sheet.row(i).concat(row)
35
39
  i += 1
36
40
  end
37
41
  end
38
- filename = options[:filename]
42
+ filename = self.parameter(options, :filename, :xls_file)
39
43
  book.write(filename)
40
44
  filename
41
45
  end
42
46
 
43
- self.register_converter(:xls_file, :multi_sheet_table_iterator) do |data, options|
44
- book = Spreadsheet.open(data[:filename])
47
+ self.register_converter(:xls_file, :multi_sheet_table_iterator) do |input, options|
48
+ filename = self.parameter(input, :filename, :input)
49
+ book = Spreadsheet.open(filename)
45
50
  book.worksheets.map do |sheet|
46
51
  iterator = lambda { |&block|
47
52
  sheet.each do |row|
@@ -5,7 +5,8 @@ class DataListConverter
5
5
 
6
6
  self.register_converter(:xlsx_file, :table_iterator) do |input, options|
7
7
  lambda { |&block|
8
- book = RubyXL::Parser.parse(input[:filename])
8
+ filename = self.parameter(input, :filename, :input)
9
+ book = RubyXL::Parser.parse(filename)
9
10
  sheet = book.worksheets[input[:sheet] || 0]
10
11
  sheet.each do |row|
11
12
  next unless row
@@ -22,11 +23,11 @@ class DataListConverter
22
23
  i = 0
23
24
  proc.call do |row|
24
25
  row.each_with_index do |v, j|
25
- sheet.add_cell(i, j, v)
26
+ sheet.add_cell(i, j, v.to_s)
26
27
  end
27
28
  i += 1
28
29
  end
29
- filename = options[:filename]
30
+ filename = self.parameter(options, :filename, :xlsx_file)
30
31
  book.write(filename)
31
32
  filename
32
33
  end
@@ -41,27 +42,28 @@ class DataListConverter
41
42
  row.each_with_index do |v, j|
42
43
  if v.kind_of?(Hash)
43
44
  # custom cell format
44
- cell = sheet.add_cell(i, j, v[:text])
45
+ cell = sheet.add_cell(i, j, v[:text].to_s)
45
46
  v.each do |k, v|
46
47
  next if k == :text
47
48
  cell.send(k, v)
48
49
  end
49
50
  cell.change_fill(v[:fill_color]) if v[:fill_color]
50
51
  else
51
- cell = sheet.add_cell(i, j, v)
52
+ cell = sheet.add_cell(i, j, v.to_s)
52
53
  end
53
54
 
54
55
  end
55
56
  i += 1
56
57
  end
57
58
  end
58
- filename = options[:filename]
59
+ filename = self.parameter(options, :filename, :xlsx_file)
59
60
  book.write(filename)
60
61
  filename
61
62
  end
62
63
 
63
- self.register_converter(:xlsx_file, :multi_sheet_table_iterator) do |data, options|
64
- book = RubyXL::Parser.parse(data[:filename])
64
+ self.register_converter(:xlsx_file, :multi_sheet_table_iterator) do |input, options|
65
+ filename = self.parameter(input, :filename, :input)
66
+ book = RubyXL::Parser.parse(filename)
65
67
  book.worksheets.map do |sheet|
66
68
  iterator = lambda { |&block|
67
69
  sheet.each do |row|
@@ -1,3 +1,3 @@
1
1
  class DataListConverter
2
- VERSION = "0.3.9".freeze
2
+ VERSION = "0.4.3".freeze
3
3
  end
@@ -40,6 +40,12 @@ describe DataListConverter do
40
40
  string.string.must_equal ".4\n.8\n.12\n"
41
41
  end
42
42
 
43
+ it 'test data format exists' do
44
+ -> {
45
+ DataListConverter.convert(:item_data, :ppp, {a: 12})
46
+ }.must_raise Exception
47
+ end
48
+
43
49
  end
44
50
 
45
51
  end
@@ -26,12 +26,30 @@ describe DataListConverter do
26
26
  string = StringIO.new
27
27
  filter = {count: {size: 4000,
28
28
  out: string,
29
- msg: "%{percent}%"}}
29
+ msg: "%{percent}%%"}}
30
30
  result = DataListConverter.convert(
31
31
  :item_iterator, :table_data, iter,
32
32
  item_iterator: {filter: filter})
33
33
  string.string.split("\n").must_equal ['total: 10000', '40.0%', '80.0%']
34
34
  end
35
35
  end
36
+
37
+ describe :remove_debug do
38
+ specify do
39
+ filter = {remove_debug: true}
40
+ item_data = [{name: "james", debug: "", a: 12}] * 2
41
+ result = DataListConverter.convert(
42
+ :item_data, :table_data, item_data,
43
+ table_iterator: {filter: filter})
44
+ result.must_equal [["name"], ["james"], ["james"]]
45
+
46
+ # check on multi_sheet
47
+ item_data = {a: [{name: "james", debug: "", a: 12}] * 2, b: [{name: 'cc', debug: "", b: 3}]*3}
48
+ result = DataListConverter.convert(
49
+ :multi_sheet_item_data, :multi_sheet_table_data, item_data,
50
+ multi_sheet_table_iterator: {table_iterator: {filter: {remove_debug: true}}})
51
+ result.must_equal(a: [["name"], ["james"], ["james"]], b: [["name"], ["cc"], ["cc"], ["cc"]])
52
+ end
53
+ end
36
54
 
37
55
  end
@@ -70,4 +70,21 @@ describe DataListConverter do
70
70
  end
71
71
  end
72
72
 
73
+
74
+ describe :flatten do
75
+ specify do
76
+ data = {a: {b: 12}, c: {d: {e: 11}}}
77
+ @c.flatten(data).must_equal({:"a:b"=>12, :"c:d:e"=>11})
78
+
79
+ # change sep
80
+ data = {a: {b: 12}, c: {d: {e: 11}}}
81
+ @c.flatten(data, '_').must_equal({:"a_b"=>12, :"c_d_e"=>11})
82
+
83
+ # set max level
84
+ data = {a: {b: 12}, c: {d: {e: {f: 11}}}}
85
+ @c.flatten(data, ':', 1).must_equal({:"a:b"=>12, :"c:d"=>{e: {f: 11}}})
86
+ data = {a: {b: 12}, c: {d: {e: {f: 11}}}}
87
+ @c.flatten(data, ':', 2).must_equal({:"a:b"=>12, :"c:d:e"=>{f: 11}})
88
+ end
89
+ end
73
90
  end
@@ -99,5 +99,36 @@ describe DataListConverter do
99
99
  end
100
100
  end
101
101
  end
102
+
103
+ describe :records do
104
+ specify do
105
+ require 'sqlite3'
106
+ require 'active_record'
107
+
108
+ ActiveRecord::Base.establish_connection(
109
+ adapter: 'sqlite3',
110
+ database: ':memory:'
111
+ )
112
+
113
+ ActiveRecord::Schema.define do
114
+ create_table :users, force: true do |t|
115
+ t.string :name
116
+ t.integer :age
117
+ end
118
+ end
119
+
120
+ class User < ActiveRecord::Base; end
121
+ (1..10).each{ |i| User.create(name: "user-#{i}", age: i+20) }
122
+
123
+ query = User.where("age > 25 and age < 27")
124
+ columns = [:name, :age]
125
+ @c.convert(:records, :item_data, query: query, columns: columns).
126
+ must_equal([{name: "user-6", age: 26}])
127
+
128
+ display = [:n, :a]
129
+ @c.convert(:records, :item_data, query: query, columns: columns, display: display).
130
+ must_equal([{n: "user-6", a: 26}])
131
+ end
132
+ end
102
133
 
103
134
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_list_converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - linjunhalida
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-19 00:00:00.000000000 Z
11
+ date: 2020-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.10.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activerecord
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '4.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '4.2'
83
111
  description: Data List Converter is a tool to convert data between different formats.
84
112
  email:
85
113
  - linjunhalida@gmail.com
@@ -132,14 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
160
  - !ruby/object:Gem::Version
133
161
  version: '0'
134
162
  requirements: []
135
- rubyforge_project:
136
- rubygems_version: 2.4.8
163
+ rubygems_version: 3.0.6
137
164
  signing_key:
138
165
  specification_version: 4
139
166
  summary: convert data between different formats
140
- test_files:
141
- - test/base_test.rb
142
- - test/filters_test.rb
143
- - test/helper_test.rb
144
- - test/testdata.rb
145
- - test/types_test.rb
167
+ test_files: []