ruby_robot 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +133 -0
  5. data/Guardfile +77 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +50 -0
  8. data/Rakefile +24 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/ruby_robot +34 -0
  12. data/exe/ruby_robot_grpc_client +53 -0
  13. data/exe/ruby_robot_grpc_server +46 -0
  14. data/exe/ruby_robot_web +19 -0
  15. data/json_schema/request.schema.json +37 -0
  16. data/json_schema/response.schema.json +24 -0
  17. data/lib/public/favicon-16x16.png +0 -0
  18. data/lib/public/favicon-32x32.png +0 -0
  19. data/lib/public/index.html +95 -0
  20. data/lib/public/swagger-ui-bundle.js +93 -0
  21. data/lib/public/swagger-ui-standalone-preset.js +13 -0
  22. data/lib/public/swagger-ui.css +3 -0
  23. data/lib/public/swagger-ui.js +8 -0
  24. data/lib/public/swagger.json +179 -0
  25. data/lib/ruby_robot.rb +16 -0
  26. data/lib/ruby_robot/cacerts.crt +92 -0
  27. data/lib/ruby_robot/construction_error.rb +4 -0
  28. data/lib/ruby_robot/grpc/robot_service.rb +102 -0
  29. data/lib/ruby_robot/grpc/ruby_robot_services_pb.rb +34 -0
  30. data/lib/ruby_robot/grpc_helper.rb +15 -0
  31. data/lib/ruby_robot/grpc_ruby/ruby_robot_pb.rb +36 -0
  32. data/lib/ruby_robot/grpc_shell.rb +85 -0
  33. data/lib/ruby_robot/netflix_tabletop.rb +14 -0
  34. data/lib/ruby_robot/placement_error.rb +4 -0
  35. data/lib/ruby_robot/robot.rb +71 -0
  36. data/lib/ruby_robot/ruby_robot.proto +53 -0
  37. data/lib/ruby_robot/schema_loader.rb +10 -0
  38. data/lib/ruby_robot/shell.rb +204 -0
  39. data/lib/ruby_robot/tabletop.rb +120 -0
  40. data/lib/ruby_robot/version.rb +3 -0
  41. data/lib/ruby_robot/webapp.rb +263 -0
  42. data/ruby_robot.gemspec +48 -0
  43. metadata +258 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 99afa9b15195b1d74b651f606e9189bd469c2438
4
+ data.tar.gz: 0f8d53802c6fa887172c300743a86ce24c3137b5
5
+ SHA512:
6
+ metadata.gz: 50699247d29c18e940404a7760f66d2e2e9be6b2e732e7134e6bc1094fd4a0a540379f731e768149f712c21efe42ff566f8344774ba322b865b5352bf00c3b5a
7
+ data.tar.gz: a763602b9959e42023c190d5ce8e44c0d4388e0a2373eb77783fbb12092c5b5acdefeb5137823ad56b3958bd58bcee4629c262e89120999256be0c9b9d7d1591
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in ruby_robot.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,133 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ruby_robot (0.1.9)
5
+ bombshell
6
+ bundler (~> 1.16)
7
+ grpc
8
+ json-schema
9
+ sinatra (< 2)
10
+ sinatra-swagger-exposer
11
+ wirble
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ addressable (2.5.2)
17
+ public_suffix (>= 2.0.2, < 4.0)
18
+ bombshell (0.1.6)
19
+ coderay (1.1.2)
20
+ diff-lcs (1.3)
21
+ faraday (0.14.0)
22
+ multipart-post (>= 1.2, < 3)
23
+ ffi (1.9.23)
24
+ formatador (0.2.5)
25
+ google-protobuf (3.5.1.2-universal-darwin)
26
+ googleapis-common-protos-types (1.0.1)
27
+ google-protobuf (~> 3.0)
28
+ googleauth (0.6.2)
29
+ faraday (~> 0.12)
30
+ jwt (>= 1.4, < 3.0)
31
+ logging (~> 2.0)
32
+ memoist (~> 0.12)
33
+ multi_json (~> 1.11)
34
+ os (~> 0.9)
35
+ signet (~> 0.7)
36
+ grpc (1.10.0-universal-darwin)
37
+ google-protobuf (~> 3.1)
38
+ googleapis-common-protos-types (~> 1.0.0)
39
+ googleauth (>= 0.5.1, < 0.7)
40
+ grpc-tools (1.10.0)
41
+ guard (2.14.2)
42
+ formatador (>= 0.2.4)
43
+ listen (>= 2.7, < 4.0)
44
+ lumberjack (>= 1.0.12, < 2.0)
45
+ nenv (~> 0.1)
46
+ notiffany (~> 0.0)
47
+ pry (>= 0.9.12)
48
+ shellany (~> 0.0)
49
+ thor (>= 0.18.1)
50
+ guard-compat (1.2.1)
51
+ guard-rspec (4.7.3)
52
+ guard (~> 2.1)
53
+ guard-compat (~> 1.1)
54
+ rspec (>= 2.99.0, < 4.0)
55
+ json-schema (2.8.0)
56
+ addressable (>= 2.4)
57
+ jwt (2.1.0)
58
+ listen (3.1.5)
59
+ rb-fsevent (~> 0.9, >= 0.9.4)
60
+ rb-inotify (~> 0.9, >= 0.9.7)
61
+ ruby_dep (~> 1.2)
62
+ little-plugger (1.1.4)
63
+ logging (2.2.2)
64
+ little-plugger (~> 1.1)
65
+ multi_json (~> 1.10)
66
+ lumberjack (1.0.12)
67
+ memoist (0.16.0)
68
+ method_source (0.9.0)
69
+ mime-types (2.6.2)
70
+ multi_json (1.13.1)
71
+ multipart-post (2.0.0)
72
+ nenv (0.3.0)
73
+ notiffany (0.1.1)
74
+ nenv (~> 0.1)
75
+ shellany (~> 0.0)
76
+ os (0.9.6)
77
+ pry (0.11.3)
78
+ coderay (~> 1.1.0)
79
+ method_source (~> 0.9.0)
80
+ public_suffix (3.0.2)
81
+ rack (1.6.9)
82
+ rack-protection (1.5.4)
83
+ rack
84
+ rack-test (0.8.3)
85
+ rack (>= 1.0, < 3)
86
+ rake (10.5.0)
87
+ rb-fsevent (0.10.2)
88
+ rb-inotify (0.9.10)
89
+ ffi (>= 0.5.0, < 2)
90
+ rspec (3.7.0)
91
+ rspec-core (~> 3.7.0)
92
+ rspec-expectations (~> 3.7.0)
93
+ rspec-mocks (~> 3.7.0)
94
+ rspec-core (3.7.1)
95
+ rspec-support (~> 3.7.0)
96
+ rspec-expectations (3.7.0)
97
+ diff-lcs (>= 1.2.0, < 2.0)
98
+ rspec-support (~> 3.7.0)
99
+ rspec-mocks (3.7.0)
100
+ diff-lcs (>= 1.2.0, < 2.0)
101
+ rspec-support (~> 3.7.0)
102
+ rspec-support (3.7.1)
103
+ ruby_dep (1.5.0)
104
+ shellany (0.0.1)
105
+ signet (0.8.1)
106
+ addressable (~> 2.3)
107
+ faraday (~> 0.9)
108
+ jwt (>= 1.5, < 3.0)
109
+ multi_json (~> 1.10)
110
+ sinatra (1.4.8)
111
+ rack (~> 1.5)
112
+ rack-protection (~> 1.4)
113
+ tilt (>= 1.3, < 3)
114
+ sinatra-swagger-exposer (0.4.0)
115
+ mime-types (~> 2.6.2)
116
+ sinatra (~> 1.4)
117
+ thor (0.20.0)
118
+ tilt (2.0.8)
119
+ wirble (0.1.3)
120
+
121
+ PLATFORMS
122
+ ruby
123
+
124
+ DEPENDENCIES
125
+ grpc-tools
126
+ guard-rspec
127
+ rack-test
128
+ rake (~> 10.0)
129
+ rspec
130
+ ruby_robot!
131
+
132
+ BUNDLED WITH
133
+ 1.16.1
data/Guardfile ADDED
@@ -0,0 +1,77 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ # guard :rspec, cmd: "bundle exec rake spec:all" do
28
+ guard :rspec, cmd: "bundle exec rspec" do
29
+ require "guard/rspec/dsl"
30
+ dsl = Guard::RSpec::Dsl.new(self)
31
+
32
+ # Feel free to open issues for suggestions and improvements
33
+
34
+ # RSpec files
35
+ rspec = dsl.rspec
36
+ watch(rspec.spec_helper) { rspec.spec_dir }
37
+ watch(rspec.spec_support) { rspec.spec_dir }
38
+ watch(rspec.spec_files)
39
+ watch(/lib\/ruby_robot\/.*.rb$/) { rspec.spec_dir }
40
+ watch(/doc\/.*.schema.json$/) { rspec.spec_dir }
41
+ # Command-line spec files
42
+ # cmd_line_spec = %r{^cmd_line_spec/.+\.rb$}
43
+ # puts cmd_line_spec
44
+ #watch(cmd_line_spec) { |m| puts m}
45
+
46
+ # Ruby files
47
+ ruby = dsl.ruby
48
+ dsl.watch_spec_files_for(ruby.lib_files)
49
+
50
+ # Rails files
51
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
52
+ dsl.watch_spec_files_for(rails.app_files)
53
+ dsl.watch_spec_files_for(rails.views)
54
+
55
+ watch(rails.controllers) do |m|
56
+ [
57
+ rspec.spec.call("routing/#{m[1]}_routing"),
58
+ rspec.spec.call("controllers/#{m[1]}_controller"),
59
+ rspec.spec.call("acceptance/#{m[1]}")
60
+ ]
61
+ end
62
+
63
+ # Rails config changes
64
+ watch(rails.spec_helper) { rspec.spec_dir }
65
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
66
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
67
+
68
+ # Capybara features specs
69
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
70
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
71
+
72
+ # Turnip features and steps
73
+ watch(%r{^spec/acceptance/(.+)\.feature$})
74
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
75
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
76
+ end
77
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Dane Avilla
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # RubyRobot
2
+
3
+ Toy code implementing robot interface for ruby coding challenge for Netflix
4
+ https://jobs.netflix.com/jobs/864893 (if dead, this URL exists at archive.org).
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'ruby_robot'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install ruby_robot
21
+
22
+ ## Usage
23
+
24
+ TODO: Write usage instructions here
25
+
26
+ ## Development
27
+
28
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
29
+
30
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
31
+
32
+ ## Versions
33
+ 0.1.9 - Add TLS support to gRPC client/server
34
+ 0.1.8 - Add gRPC support to the 'ruby_robot' REPL
35
+ 0.1.7 - Add gRPC client/server
36
+ 0.1.6 - Add JSON schema validation of the responses returned to clients from POST /place; simplify schemas
37
+ 0.1.5 - Add /remove call to remove the singleton robot from the tabletop in the HTTP API
38
+ 0.1.4 - Fix dependency issue
39
+ 0.1.3 - Fix bundler setup for ruby_robot; move json schemas from 'doc' to 'json_schema'
40
+ 0.1.2 - Add checks so web app will bind to all interfaces when run under Docker
41
+ 0.1.1 - Adding bundler as a runtime dependency
42
+ 0.1.0 - Initial release
43
+
44
+ ## Contributing
45
+
46
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ruby_robot.
47
+
48
+ ## License
49
+
50
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ RSpec::Core::RakeTask.new(:cmd_line_spec) { |t|
8
+ t.pattern = 'cmd_line_spec/**{,/*/**}/*_spec.rb'
9
+ }
10
+
11
+ task :cmd_line_spec => ['install:local']
12
+
13
+ # For right now, run this from lib/ruby_robot to build the protobuf stubs:
14
+ #
15
+ # protoc -I protos --ruby_out=lib --grpc_out=lib --plugin=protoc-gen-grpc=`which grpc_ruby_plugin` robot.proto
16
+ #
17
+
18
+ namespace :spec do
19
+ desc "Run rspec tests and command-line tests"
20
+ task :all => ['spec', 'cmd_line_spec']
21
+ end
22
+
23
+ task default: :spec
24
+
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ruby_robot"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/ruby_robot ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+ require 'ruby_robot'
8
+ require 'uri'
9
+ require 'optparse'
10
+
11
+ #
12
+ # TODO: use getoptlong (or optparse) to parse args, including support for --help.
13
+ #
14
+ if ARGV.size == 1
15
+ uri, *rest = ARGV
16
+
17
+ STDOUT.puts "Welcome to the shell; press 'tab' to see available commands"
18
+ STDOUT.puts "(tab-complete is also enabled)"
19
+
20
+ if uri.strip.downcase == 'standalone'
21
+ ::Bombshell.launch(::RubyRobot::Shell)
22
+ else
23
+ ::RubyRobot::GrpcShell.remote_url = URI.parse(ARGV.first)
24
+ ::Bombshell.launch(::RubyRobot::GrpcShell)
25
+ end
26
+ elsif ARGV.empty?
27
+ ::Bombshell.launch(::RubyRobot::Shell)
28
+ else
29
+ STDERR.puts " Usage: #{$0} [gRPC_Remote_URL|standalone]"
30
+ STDERR.puts " Standalone Example: #{$0} standalone"
31
+ STDERR.puts " gRPC Localhost Example: #{$0} grpc://127.0.0.1:31310"
32
+ STDERR.puts "gRPC Remote TLS Example: #{$0} grpcs://netflix.avilla.net:31310"
33
+ exit 1
34
+ end
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+ $: << File.dirname(__FILE__) + '/../lib/ruby_robot/grpc_ruby'
8
+ require 'ruby_robot/grpc/ruby_robot_services_pb'
9
+ require 'ruby_robot'
10
+ require 'json'
11
+
12
+ def main
13
+ stub = ::RubyRobot::RubyRobot::Stub.new('localhost:31310', :this_channel_is_insecure)
14
+ stub.remove(Google::Protobuf::Empty.new)
15
+ puts stub.left( Google::Protobuf::Empty.new).error.message
16
+ puts stub.move( Google::Protobuf::Empty.new).error.message
17
+ puts stub.remove(Google::Protobuf::Empty.new)
18
+ puts stub.report(Google::Protobuf::Empty.new).error.message
19
+ puts stub.right( Google::Protobuf::Empty.new).error.message
20
+
21
+ # Replicate tests from original spec: PLACE 0,0,NORTH; MOVE; REPORT
22
+ stub.remove(Google::Protobuf::Empty.new)
23
+ cs = stub.place(::RubyRobot::RubyRobotRequest.new(x: 0, y: 0, direction: :NORTH)).current_state
24
+ stub.move(Google::Protobuf::Empty.new)
25
+ puts stub.report(Google::Protobuf::Empty.new).current_state.to_json
26
+
27
+ # PLACE 0,0,NORTH; LEFT; REPORT
28
+ stub.remove(Google::Protobuf::Empty.new)
29
+ cs = stub.place(::RubyRobot::RubyRobotRequest.new(x: 0, y: 0, direction: :NORTH)).current_state
30
+ stub.left(Google::Protobuf::Empty.new)
31
+ puts stub.report(Google::Protobuf::Empty.new).current_state.to_json
32
+
33
+ # PLACE 1,2,EAST; MOVE; MOVE; LEFT; MOVE; REPORT
34
+ stub.remove(Google::Protobuf::Empty.new)
35
+ cs = stub.place(::RubyRobot::RubyRobotRequest.new(x: 1, y: 2, direction: :EAST)).current_state
36
+ stub.move(Google::Protobuf::Empty.new)
37
+ stub.move(Google::Protobuf::Empty.new)
38
+ stub.left(Google::Protobuf::Empty.new)
39
+ stub.move(Google::Protobuf::Empty.new)
40
+ puts stub.report(Google::Protobuf::Empty.new).current_state.to_json
41
+
42
+ # PLACE 1,2,EAST; MOVE; MOVE; LEFT; MOVE; PLACE 100,1,SOUTH; REPORT
43
+ stub.remove(Google::Protobuf::Empty.new)
44
+ cs = stub.place(::RubyRobot::RubyRobotRequest.new(x: 1, y: 2, direction: :EAST)).current_state
45
+ stub.move(Google::Protobuf::Empty.new)
46
+ stub.move(Google::Protobuf::Empty.new)
47
+ stub.left(Google::Protobuf::Empty.new)
48
+ stub.move(Google::Protobuf::Empty.new)
49
+ puts stub.place(::RubyRobot::RubyRobotRequest.new(x: 100, y: 1, direction: :SOUTH)).current_state
50
+ puts stub.report(Google::Protobuf::Empty.new).current_state.to_json
51
+ end
52
+
53
+ main