shellfish 0.0.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.
@@ -0,0 +1,19 @@
1
+ *.swp
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ vendor
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ -fd -c --require=spec_helper
@@ -0,0 +1,7 @@
1
+ ChangeLog of Shellfish
2
+ ======================
3
+
4
+ 0.0.1 released 2012-07-28
5
+ -------------------------
6
+
7
+ - Initial release.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Yuya Takeyama
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,37 @@
1
+ # Shellfish
2
+
3
+ Solve problem, learn shell commands.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'shellfish'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install shellfish
18
+
19
+ ## Usage
20
+
21
+ $ shellfish PROBLEM_DEFINITION_FILE [...]
22
+
23
+ ## Writing Problem Definition File
24
+
25
+ It's can be written with DSL.
26
+
27
+ subject "Subject of the problem"
28
+ desc "Description of the problem"
29
+ expected "Expected output"
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'shellfish'
4
+ require 'shellfish/application'
5
+
6
+ app = Shellfish::Application.new(ARGV.dup)
7
+ app.start
@@ -0,0 +1,18 @@
1
+ subject "FizzBuzz (1 ~ 15)"
2
+
3
+ __END__
4
+ 1
5
+ 2
6
+ Fizz
7
+ 4
8
+ Buzz
9
+ Fizz
10
+ 7
11
+ 8
12
+ Fizz
13
+ Buzz
14
+ 11
15
+ Fizz
16
+ 13
17
+ 14
18
+ FizzBuzz
@@ -0,0 +1,4 @@
1
+ require "shellfish/version"
2
+
3
+ module Shellfish
4
+ end
@@ -0,0 +1,128 @@
1
+ require 'shellfish/problem_loader'
2
+ require 'rspec/expectations/differ'
3
+ require 'termcolor'
4
+ require 'optparse'
5
+ require 'readline'
6
+
7
+ module Shellfish
8
+ class QuitException < ::Exception; end
9
+ class NextProblemException < ::Exception; end
10
+ class SkipEvaluationException < ::Exception; end
11
+
12
+ class Application
13
+ def initialize(argv)
14
+ @argv = argv
15
+ if @argv.empty?
16
+ @argv = [File.expand_path('../../examples/fizzbuzz.rb', File.dirname(__FILE__))]
17
+ end
18
+ @loader = ProblemLoader.new
19
+ @differ = RSpec::Expectations::Differ.new
20
+ end
21
+
22
+ def start
23
+ opt = OptionParser.new
24
+ opt.version = VERSION
25
+
26
+ opt.parse!(@argv)
27
+ play
28
+ end
29
+
30
+ def play
31
+ @problem_count = @argv.size
32
+ @current_count = 1
33
+ @argv.each do |file|
34
+ try_problem @loader.load(file)
35
+ @current_count += 1
36
+ end
37
+ rescue QuitException
38
+ puts "Quitting shellfish..."
39
+ ensure
40
+ puts "Good bye."
41
+ end
42
+
43
+ def try_problem(problem)
44
+ show_problem(problem)
45
+ while input = ::Readline.readline('shellfish $ ', true)
46
+ begin
47
+ on_skip if input =~ /^\s*:(?:skip|next)\s*$/
48
+ on_quit if input =~ /^\s*(?::?exit|:quit)\s*$/
49
+ on_show_problem(problem) if input =~ /^\s*:show\s*$/
50
+
51
+ output = `#{input}`
52
+ if problem.expected_result != output
53
+ on_ng problem, input, output
54
+ else
55
+ on_ok problem, input, output
56
+ end
57
+ puts
58
+ rescue NextProblemException
59
+ break
60
+ rescue SkipEvaluationException
61
+ end
62
+ end
63
+ end
64
+
65
+ def on_ok(problem, input, output)
66
+ puts "<green>OK</green>".termcolor
67
+ puts
68
+ show_string output
69
+ puts "<green>Congratulations!</green>".termcolor
70
+ puts
71
+ raise NextProblemException
72
+ end
73
+
74
+ def on_ng(problem, input, output)
75
+ puts "<red>NG</red>".termcolor
76
+ puts
77
+ show_diff output, problem.expected_result
78
+ end
79
+
80
+ def on_skip
81
+ puts "<yellow>Skipped</yellow>".termcolor
82
+ raise NextProblemException
83
+ end
84
+
85
+ def on_quit
86
+ raise QuitException
87
+ end
88
+
89
+ def on_show_problem(problem)
90
+ show_problem problem
91
+ raise SkipEvaluationException
92
+ end
93
+
94
+ def show_diff(output, expected)
95
+ diff = @differ.diff_as_string(output, expected).gsub(/^\n+/, '')
96
+ colored_diff = ''
97
+ diff.each_line do |line|
98
+ if line[0] == '@'
99
+ colored_diff += "<green><bold>#{line}</bold></green>".termcolor
100
+ elsif line[0] == '+'
101
+ colored_diff += "<blue><bold>#{line}</bold></blue>".termcolor
102
+ elsif line[0] == '-'
103
+ colored_diff += "<red><bold>#{line}</bold></red>".termcolor
104
+ else
105
+ colored_diff += line
106
+ end
107
+ end
108
+ show_string colored_diff
109
+ end
110
+
111
+ def show_problem(problem)
112
+ puts ("<blue>Problem</blue> (#{@current_count}/#{@problem_count}): " +
113
+ "<bold>#{problem.subject}</bold>").termcolor
114
+ puts "Description: #{problem.description}" if problem.desc?
115
+ puts
116
+ puts "<bold>Expected Result:</bold>".termcolor
117
+ show_string "<cyan>#{problem.expected_result}</cyan>".termcolor
118
+ puts
119
+ end
120
+
121
+ def show_string(string)
122
+ puts "-" * 72
123
+ print string
124
+ puts
125
+ puts "-" * 72
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,16 @@
1
+ module Shellfish
2
+ class Problem
3
+ attr_accessor :subject, :description, :expected_result
4
+ alias expected expected_result
5
+ alias expected= expected_result=
6
+
7
+ def subject?
8
+ !(@subject.nil?)
9
+ end
10
+
11
+ def description?
12
+ !(@description.nil?)
13
+ end
14
+ alias desc? description?
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module Shellfish
2
+ class ProblemDsl
3
+ attr_reader :problem
4
+
5
+ def initialize(problem, &block)
6
+ @problem = problem
7
+ instance_eval(&block) if block_given?
8
+ end
9
+
10
+ def subject(text)
11
+ @problem.subject = text
12
+ end
13
+
14
+ def description(text)
15
+ @problem.description = text
16
+ end
17
+ alias desc description
18
+
19
+ def expected_result(text)
20
+ @problem.expected_result = text
21
+ end
22
+ alias expected expected_result
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ require 'shellfish/problem'
2
+ require 'shellfish/problem_dsl'
3
+
4
+ module Shellfish
5
+ class ProblemLoader
6
+ def load(file)
7
+ f = open(file)
8
+ result = f.read
9
+ f.close
10
+ load_from_string(result)
11
+ end
12
+
13
+ def load_from_string(input)
14
+ dsl, data = input.split("__END__\n")
15
+ script = <<-EOS
16
+ Shellfish::ProblemDsl.new(Shellfish::Problem.new) {
17
+ #{dsl}
18
+ }.problem
19
+ EOS
20
+ problem = eval script, TOPLEVEL_BINDING
21
+ problem.expected_result = data if data
22
+ problem
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Shellfish
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/shellfish/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Yuya Takeyama"]
6
+ gem.email = ["sign.of.the.wolf.pentagram@gmail.com"]
7
+ gem.description = %q{Solve problems, learn shell commands}
8
+ gem.summary = %q{Solve problems, learn shell commands}
9
+ gem.homepage = "https://github.com/yuya-takeyama/shellfish"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "shellfish"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Shellfish::VERSION
17
+
18
+ gem.add_dependency 'diff-lcs', '~> 1.1.3'
19
+ gem.add_dependency 'termcolor'
20
+ gem.add_dependency 'rspec-expectations'
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'guard-rspec'
24
+ end
@@ -0,0 +1,40 @@
1
+ require 'shellfish/problem_loader'
2
+
3
+ module Shellfish
4
+ describe ProblemLoader do
5
+ let(:loader) { Shellfish::ProblemLoader.new }
6
+
7
+ describe '#load_from_string' do
8
+ subject { loader.load_from_string(input) }
9
+ let(:input) { '' }
10
+
11
+ it { should be_a(Problem) }
12
+
13
+ context 'has subject' do
14
+ let(:input) { 'subject "Subject of the problem"' }
15
+ its(:subject) { should == "Subject of the problem" }
16
+ end
17
+
18
+ context 'has description' do
19
+ let(:input) { 'desc "Description of the problem"' }
20
+ its(:description) { should == "Description of the problem" }
21
+ end
22
+
23
+ context 'has expected result' do
24
+ let(:input) { 'expected "Expected result of the problem"' }
25
+ its(:expected) { should == "Expected result of the problem" }
26
+ end
27
+
28
+ context 'has expected result as data field' do
29
+ let(:input) {
30
+ "__END__\n" +
31
+ "foo\n" +
32
+ "bar\n" +
33
+ "baz\n"
34
+ }
35
+
36
+ its(:expected) { should == "foo\nbar\nbaz\n" }
37
+ end
38
+ end
39
+ end
40
+ end
File without changes
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shellfish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yuya Takeyama
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: diff-lcs
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: termcolor
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec-expectations
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard-rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Solve problems, learn shell commands
95
+ email:
96
+ - sign.of.the.wolf.pentagram@gmail.com
97
+ executables:
98
+ - shellfish
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - .gitignore
103
+ - .rspec
104
+ - ChangeLog.md
105
+ - Gemfile
106
+ - Guardfile
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - bin/shellfish
111
+ - examples/fizzbuzz.rb
112
+ - lib/shellfish.rb
113
+ - lib/shellfish/application.rb
114
+ - lib/shellfish/problem.rb
115
+ - lib/shellfish/problem_dsl.rb
116
+ - lib/shellfish/problem_loader.rb
117
+ - lib/shellfish/version.rb
118
+ - shellfish.gemspec
119
+ - spec/shellfish/problem_loader_spec.rb
120
+ - spec/spec_helper.rb
121
+ homepage: https://github.com/yuya-takeyama/shellfish
122
+ licenses: []
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ segments:
134
+ - 0
135
+ hash: 1692564327382767151
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
143
+ - 0
144
+ hash: 1692564327382767151
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.23
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Solve problems, learn shell commands
151
+ test_files:
152
+ - spec/shellfish/problem_loader_spec.rb
153
+ - spec/spec_helper.rb