basehangul 1.1.0 → 1.2.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
  SHA1:
3
- metadata.gz: 5dea832635fe4ba4c9cb0e698175e776ebc273ce
4
- data.tar.gz: af201548ca14b381e7cad53b6674acb988b87c79
3
+ metadata.gz: 1f556466ab0b3e2d7eda2d4331d0f5bd467ed8a9
4
+ data.tar.gz: b71091f342d216e95534be3fef902043f8324b1c
5
5
  SHA512:
6
- metadata.gz: 9e02f9167a48cb7a28c3328a2a216d5b2f6ca084312c9c3df2aff4f505137139348e3295dcc857962cd9fbb62a1aab3c77e1c8b0ea3f86254bd1894b67091cd4
7
- data.tar.gz: f09e00ca1d6d6745ca3ad7e511d25de23174906243e1117739feac6def022317293ebdc1449f288811cf1f85d32fad12889faa9ab6dda2ac254b0f164b1d2056
6
+ metadata.gz: 9608d251910fe633fa334437bdc826fb19f081bb02838bc3ac20f0df242073d0aa6f9c7ba4cd98025e8b1f6066b0f86a50d95a185904f166d7d1c1dddf416e43
7
+ data.tar.gz: 9f95afa048a10db337d0b1dc91cbee4f3b8822f495ba739a833828e57301692cba754fd2c4736f83d2714d08278d96c2b908b70d7c1296fc755fa7c09ffaed87
@@ -1,15 +1,10 @@
1
1
  # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2014-11-08 01:14:38 +0900 using RuboCop version 0.27.0.
2
+ # on 2014-11-10 01:37:53 +0900 using RuboCop version 0.27.1.
3
3
  # The point is for the user to remove these configuration records
4
4
  # one by one as the offenses are removed from the code base.
5
5
  # Note that changes in the inspected code, or installation of new
6
6
  # versions of RuboCop, may require this file to be generated again.
7
7
 
8
- # Offense count: 3
9
- Metrics/AbcSize:
10
- Max: 21
11
-
12
8
  # Offense count: 1
13
- # Configuration parameters: CountComments.
14
- Metrics/MethodLength:
15
- Max: 15
9
+ Metrics/AbcSize:
10
+ Max: 19
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 (2014-11-12)
4
+
5
+ - Implement CLI of BaseHangul
6
+
3
7
  ## 1.1.0 (2014-11-08)
4
8
 
5
9
  - Make `BaseHangul.decode` to ignore invalid characters
data/README.md CHANGED
@@ -39,6 +39,42 @@ BaseHangul.decode('넥라똔먈늴멥갯놓궂뗐밸뮤뉴뗐뀄굡덜멂똑뚤'
39
39
  # => 'This is an encoded string'
40
40
  ```
41
41
 
42
+ Run `basehangul` with no arguments to encode binary through terminal input.
43
+
44
+ ``` sh
45
+ basehangul
46
+ ```
47
+
48
+ Or pass `basehangul` a file to encode.
49
+
50
+ ``` sh
51
+ basehangul binary.txt
52
+ ```
53
+
54
+ Run `basehangul` with no arguments to decode BaseHangul string through terminal input.
55
+
56
+ ``` sh
57
+ basehangul -D
58
+ ```
59
+
60
+ Or pass `basehangul` a file to decode.
61
+
62
+ ``` sh
63
+ basehangul -D basehangul.txt
64
+ ```
65
+
66
+ For additional command-line options:
67
+
68
+ ``` sh
69
+ basehangul -h
70
+ ```
71
+
72
+ Command flag | Description
73
+ ----------------|--------------------
74
+ `-D, --decode` | Decode the input.
75
+ `-h, --help` | Print this message.
76
+ `-v, --version` | Print version.
77
+
42
78
  ## Contributing
43
79
 
44
80
  1. Fork it (https://github.com/yous/basehangul/fork)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('../../lib', File.realpath(__FILE__)))
5
+ require 'basehangul'
6
+
7
+ cli = BaseHangul::CLI.new
8
+ exit cli.run
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'basehangul/version'
4
4
  require 'basehangul/utils'
5
+ require 'basehangul/option'
6
+ require 'basehangul/cli'
5
7
 
6
8
  # Human-readable binary encoding.
7
9
  module BaseHangul
@@ -46,15 +48,7 @@ module BaseHangul
46
48
  #
47
49
  # Returns the String decoded binary.
48
50
  def self.decode(str)
49
- indices = str.each_char.map { |ch| Utils.to_index(ch) }
50
- binary = indices.map do |index|
51
- case index
52
- when 0..1023 then index.to_s(2).rjust(10, '0')
53
- when 1024..1027 then (index - 1024).to_s(2).rjust(2, '0')
54
- end
55
- end.join
56
- binary = binary[0..-(binary.size % 8 + 1)]
57
- [binary].pack('B*')
51
+ Utils.decode_indices(str.each_char.map { |ch| Utils.to_index(ch) })
58
52
  end
59
53
 
60
54
  # Public: Decode BaseHangul string.
@@ -71,13 +65,6 @@ module BaseHangul
71
65
  indices << index
72
66
  end
73
67
  fail ArgumentError, MSG_INVALID_PADDING unless str =~ REGEX_BASEHANGUL
74
- binary = indices.map do |index|
75
- case index
76
- when 0..1023 then index.to_s(2).rjust(10, '0')
77
- when 1024..1027 then (index - 1024).to_s(2).rjust(2, '0')
78
- end
79
- end.join
80
- binary = binary[0..-(binary.size % 8 + 1)]
81
- [binary].pack('B*')
68
+ Utils.decode_indices(indices)
82
69
  end
83
70
  end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ module BaseHangul
4
+ # Handle command line interfaces logic.
5
+ class CLI
6
+ # Initialize a CLI.
7
+ def initialize
8
+ @options = {}
9
+ end
10
+
11
+ # Entry point for the application logic. Process command line arguments and
12
+ # run the BaseHangul.
13
+ #
14
+ # args - An Array of Strings user passed.
15
+ #
16
+ # Returns an Integer UNIX exit code.
17
+ def run(args = ARGV)
18
+ @options, paths = Option.new.parse(args)
19
+ source = paths.empty? ? $stdin.read : IO.read(paths[0])
20
+ if @options[:decode]
21
+ puts BaseHangul.decode(source)
22
+ else
23
+ puts BaseHangul.encode(source)
24
+ end
25
+ 0
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ require 'optparse'
4
+
5
+ module BaseHangul
6
+ # Handle command line options.
7
+ class Option
8
+ # Initialize a Option.
9
+ def initialize
10
+ @options = {}
11
+ end
12
+
13
+ # Parse the passed arguments to a Hash.
14
+ #
15
+ # args - An Array of Strings containing options.
16
+ #
17
+ # Returns an Array containing a Hash options and an Array of Strings
18
+ # remaining arguments.
19
+ def parse(args)
20
+ OptionParser.new do |opts|
21
+ opts.banner = 'Usage: basehangul [options] [source]'
22
+
23
+ add_options(opts)
24
+ add_options_on_tail(opts)
25
+ end.parse!(args)
26
+ [@options, args]
27
+ end
28
+
29
+ private
30
+
31
+ # Add command line options.
32
+ #
33
+ # opts - An OptionParser object to add options.
34
+ #
35
+ # Returns nothing.
36
+ def add_options(opts)
37
+ opts.on('-D', '--decode', 'Decode the input.') do
38
+ @options[:decode] = true
39
+ end
40
+ end
41
+
42
+ # Add command line options printed at tail.
43
+ #
44
+ # opts - An OptionParser object to add options.
45
+ #
46
+ # Returns nothing.
47
+ def add_options_on_tail(opts)
48
+ opts.on_tail('-h', '--help', 'Print this message.') do
49
+ puts opts
50
+ exit 0
51
+ end
52
+
53
+ opts.on_tail('-v', '--version', 'Print version.') do
54
+ puts Version::STRING
55
+ exit 0
56
+ end
57
+ end
58
+ end
59
+ end
@@ -58,6 +58,25 @@ module BaseHangul
58
58
  .encode(Encoding::UTF_8)
59
59
  end
60
60
 
61
+ # Convert BaseHangul indices to hangul string.
62
+ #
63
+ # Examples
64
+ #
65
+ # decode_indices([196, -1, -1, -1])
66
+ # # => '꺽흐흐흐'
67
+ #
68
+ # Returns the String decoded binary.
69
+ def self.decode_indices(indices)
70
+ binary = indices.map do |index|
71
+ case index
72
+ when 0..1023 then index.to_s(2).rjust(10, '0')
73
+ when 1024..1027 then (index - 1024).to_s(2).rjust(2, '0')
74
+ end
75
+ end.join
76
+ binary = binary[0..-(binary.size % 8 + 1)]
77
+ [binary].pack('B*')
78
+ end
79
+
61
80
  # Slice a string into chunks of a given size.
62
81
  #
63
82
  # str - The String to slice.
@@ -3,6 +3,6 @@
3
3
  module BaseHangul
4
4
  # Holds the BaseHangul version information.
5
5
  module Version
6
- STRING = '1.1.0'
6
+ STRING = '1.2.0'
7
7
  end
8
8
  end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe BaseHangul::CLI do
4
+ include FileHelper
5
+ include_context 'isolated environment'
6
+
7
+ subject(:cli) { described_class.new }
8
+
9
+ before(:example) { $stdout = StringIO.new }
10
+ after(:example) { $stdout = STDOUT }
11
+
12
+ it 'encodes text file passed as an argument' do
13
+ create_file('binary.txt',
14
+ 'ABCDE' \
15
+ '12345' \
16
+ '가나다라마' \
17
+ "\u3000")
18
+ expect(cli.run(['binary.txt'])).to be(0)
19
+ expect($stdout.string)
20
+ .to eq("꿸거껫경꺽먹께겔법많겡밌뙨렷륑꽥뜰봤륑밖밞갑가흐\n")
21
+ end
22
+
23
+ it 'encodes string passed as an stdin argument' do
24
+ allow($stdin).to receive(:read).once
25
+ .and_return('ABCDE' \
26
+ '12345' \
27
+ '가나다라마' \
28
+ "\u3000")
29
+ expect(cli.run([])).to be(0)
30
+ expect($stdout.string)
31
+ .to eq("꿸거껫경꺽먹께겔법많겡밌뙨렷륑꽥뜰봤륑밖밞갑가흐\n")
32
+ end
33
+
34
+ describe '-D/--decode' do
35
+ it 'decodes text file passed as an argument' do
36
+ create_file('basehangul.txt',
37
+ ['꿸거껫경꺽먹께겔법많겡밌뙨렷륑꽥뜰봤륑밖밞갑가흐'])
38
+ expect(cli.run(['--decode', 'basehangul.txt'])).to be(0)
39
+ expect($stdout.string).to eq('ABCDE' \
40
+ '12345' \
41
+ '가나다라마' \
42
+ "\u3000\n")
43
+ end
44
+
45
+ it 'decodes string passed as an stdin argument' do
46
+ allow($stdin).to receive(:read).once
47
+ .and_return('꿸거껫경꺽먹께겔법많겡밌뙨렷륑꽥뜰봤륑밖밞갑가흐')
48
+ expect(cli.run(['--decode'])).to be(0)
49
+ expect($stdout.string) .to eq('ABCDE' \
50
+ '12345' \
51
+ '가나다라마' \
52
+ "\u3000\n")
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe BaseHangul::Option do
4
+ include ExitCodeMatchers
5
+
6
+ subject(:option) { described_class.new }
7
+
8
+ before(:example) { $stdout = StringIO.new }
9
+ after(:example) { $stdout = STDOUT }
10
+
11
+ describe 'option' do
12
+ describe '-h/--help' do
13
+ it 'exits cleanly' do
14
+ expect { option.parse(['-h']) }.to exit_with_code(0)
15
+ expect { option.parse(['--help']) }.to exit_with_code(0)
16
+ end
17
+
18
+ it 'shows help text' do
19
+ begin
20
+ option.parse(['--help'])
21
+ rescue SystemExit # rubocop:disable Lint/HandleExceptions
22
+ end
23
+
24
+ expected_help = <<-END
25
+ Usage: basehangul [options] [source]
26
+ -D, --decode Decode the input.
27
+ -h, --help Print this message.
28
+ -v, --version Print version.
29
+ END
30
+
31
+ expect($stdout.string).to eq(expected_help)
32
+ end
33
+ end
34
+
35
+ describe '-v/--version' do
36
+ it 'exits cleanly' do
37
+ expect { option.parse(['-v']) }.to exit_with_code(0)
38
+ expect { option.parse(['--version']) }.to exit_with_code(0)
39
+ expect($stdout.string).to eq("#{BaseHangul::Version::STRING}\n" * 2)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -51,6 +51,62 @@ RSpec.describe BaseHangul::Utils do
51
51
  end
52
52
  end
53
53
 
54
+ describe '.decode_indices' do
55
+ it 'returns empty string for empty array' do
56
+ decoded = utils.decode_indices([])
57
+ expect(decoded).to eq('')
58
+ end
59
+
60
+ context 'when there is no padding indices' do
61
+ it 'decodes indices to binary' do
62
+ decoded = utils.decode_indices([196, 803, 216, 354])
63
+ expect(decoded).to eq('123ab')
64
+ decoded = utils.decode_indices([196, 803, 217, 0])
65
+ expect(decoded).to eq("123d\x00")
66
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 526, 304])
67
+ expect(decoded).to eq('1234567890')
68
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 537, 0])
69
+ expect(decoded).to eq("12345678d\x00")
70
+ end
71
+ end
72
+
73
+ context 'when there are padding characters' do
74
+ it 'decodes indices to binary' do
75
+ decoded = utils.decode_indices([196, -1, -1, -1])
76
+ expect(decoded).to eq('1')
77
+ decoded = utils.decode_indices([196, 800, -1, -1])
78
+ expect(decoded).to eq('12')
79
+ decoded = utils.decode_indices([196, 803, 192, -1])
80
+ expect(decoded).to eq('123')
81
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 880, -1, -1])
82
+ expect(decoded).to eq('1234567')
83
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 512, -1])
84
+ expect(decoded).to eq('12345678')
85
+ end
86
+ end
87
+
88
+ context 'when there are special characters' do
89
+ it 'decodes indices to binary' do
90
+ decoded = utils.decode_indices([196, 803, 217, 1024])
91
+ expect(decoded).to eq('123d')
92
+ decoded = utils.decode_indices([196, 803, 217, 1025])
93
+ expect(decoded).to eq('123e')
94
+ decoded = utils.decode_indices([196, 803, 217, 1026])
95
+ expect(decoded).to eq('123f')
96
+ decoded = utils.decode_indices([196, 803, 217, 1027])
97
+ expect(decoded).to eq('123g')
98
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 537, 1024])
99
+ expect(decoded).to eq('12345678d')
100
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 537, 1025])
101
+ expect(decoded).to eq('12345678e')
102
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 537, 1026])
103
+ expect(decoded).to eq('12345678f')
104
+ decoded = utils.decode_indices([196, 803, 205, 53, 216, 883, 537, 1027])
105
+ expect(decoded).to eq('12345678g')
106
+ end
107
+ end
108
+ end
109
+
54
110
  describe '.chunks' do
55
111
  context 'with empty string' do
56
112
  it 'returns an empty array' do
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ # Matches exit code of block with SystemExit.
4
+ module ExitCodeMatchers
5
+ RSpec::Matchers.define :exit_with_code do |code|
6
+ supports_block_expectations
7
+ actual = nil
8
+ match do |block|
9
+ begin
10
+ block.call
11
+ rescue SystemExit => e
12
+ actual = e.status
13
+ end
14
+ actual && actual == code
15
+ end
16
+ failure_message do
17
+ "expected block to call exit(#{code}) but exit" +
18
+ (actual.nil? ? ' not called' : "(#{actual}) was called")
19
+ end
20
+ failure_message_when_negated do
21
+ "expected block not to call exit(#{code})"
22
+ end
23
+ description do
24
+ "expect block to call exit(#{code})"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+
5
+ # Util methods for processing file.
6
+ module FileHelper
7
+ # Create file with at given path with given content. Ensure parent directories
8
+ # are exists.
9
+ #
10
+ # path - An String path of file.
11
+ # content - An String or an Array of Strings content of file.
12
+ #
13
+ # Returns nothing.
14
+ def create_file(path, content)
15
+ file_path = File.expand_path(path)
16
+ dir_path = File.dirname(file_path)
17
+ FileUtils.makedirs(dir_path) unless File.exist?(dir_path)
18
+ write_file(path, content)
19
+ end
20
+
21
+ # Write file content at given path.
22
+ #
23
+ # path - An String path of file.
24
+ # content - An String or an Array of Strings content of file.
25
+ #
26
+ # Returns nothing.
27
+ def write_file(path, content)
28
+ File.open(path, 'w') do |file|
29
+ case content
30
+ when ''
31
+ # Create empty file.
32
+ when String
33
+ file.write(content)
34
+ when Array
35
+ file.puts(content.join("\n"))
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tmpdir'
4
+
5
+ RSpec.shared_context 'isolated environment' do
6
+ around do |example|
7
+ Dir.mktmpdir do |tmpdir|
8
+ tmpdir = File.realpath(tmpdir)
9
+ Dir.chdir(tmpdir) do
10
+ example.run
11
+ end
12
+ end
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basehangul
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ChaYoung You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-07 00:00:00.000000000 Z
11
+ date: 2014-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -83,7 +83,8 @@ dependencies:
83
83
  description: Human-readable binary encoding, BaseHangul for Ruby.
84
84
  email:
85
85
  - yousbe@gmail.com
86
- executables: []
86
+ executables:
87
+ - basehangul
87
88
  extensions: []
88
89
  extra_rdoc_files: []
89
90
  files:
@@ -98,14 +99,22 @@ files:
98
99
  - README.md
99
100
  - Rakefile
100
101
  - basehangul.gemspec
102
+ - bin/basehangul
101
103
  - lib/basehangul.rb
104
+ - lib/basehangul/cli.rb
105
+ - lib/basehangul/option.rb
102
106
  - lib/basehangul/utils.rb
103
107
  - lib/basehangul/version.rb
108
+ - spec/basehangul/cli_spec.rb
109
+ - spec/basehangul/option_spec.rb
104
110
  - spec/basehangul/utils_spec.rb
105
111
  - spec/basehangul/version_spec.rb
106
112
  - spec/basehangul_spec.rb
107
113
  - spec/spec_helper.rb
108
114
  - spec/support/coverage.rb
115
+ - spec/support/exit_code_matchers.rb
116
+ - spec/support/file_helper.rb
117
+ - spec/support/isolated_environment.rb
109
118
  - spec/support/shared_decode.rb
110
119
  homepage: ''
111
120
  licenses:
@@ -132,9 +141,14 @@ signing_key:
132
141
  specification_version: 4
133
142
  summary: Human-readable binary encoding, BaseHangul for Ruby.
134
143
  test_files:
144
+ - spec/basehangul/cli_spec.rb
145
+ - spec/basehangul/option_spec.rb
135
146
  - spec/basehangul/utils_spec.rb
136
147
  - spec/basehangul/version_spec.rb
137
148
  - spec/basehangul_spec.rb
138
149
  - spec/spec_helper.rb
139
150
  - spec/support/coverage.rb
151
+ - spec/support/exit_code_matchers.rb
152
+ - spec/support/file_helper.rb
153
+ - spec/support/isolated_environment.rb
140
154
  - spec/support/shared_decode.rb