basehangul 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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