coderetreat 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +15 -0
  2. data/bin/cr +15 -0
  3. data/lib/coderetreat.rb +159 -0
  4. metadata +47 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODVjZmI1ZjY0ZjBkMmNkNmMyMTA2ZGY3ZGVkOWQzNjRhZGRiMDI0Yw==
5
+ data.tar.gz: !binary |-
6
+ MjgwNjBmZjc3NTNhZWNkMDkxMmM3MDI2NTg5ZTA1ZjY3YmY1NzhhMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OWIyMzRlOGNlMmY5MTQwOWMxOGQ3NGJhZjU3Nzk5MjBmMDdjNWM2NmJhOTE2
10
+ YzFiNjU0Y2VmMzRmNWE5Y2FhODk0ZjY1NzcwMjQ2N2ZjOWVjM2I3MGQ3OWFj
11
+ ZWRkNmNlMTgzMWZmYjg5ODE2OTdiNDYyMjAwNDMyZDA2NzgxYWI=
12
+ data.tar.gz: !binary |-
13
+ MjYxODMyYWE4YmRmOWE5ODljMTgzZWM5YzgyN2YyMjNkMDgxNGViNTUwMWZl
14
+ YTAzODkyOWVlZTkzN2U4MDMzMjA5MDFhZTIyMjk3ZjM1ZmZmOTVmYzU2Zjc1
15
+ NGI4MjQyNDgyOWM5MjI4ZTc4MDQ4MzA3OTJjNGIzMThjMjhmN2Y=
data/bin/cr ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ if ARGV.length > 0
3
+ file = ARGV[0]
4
+
5
+ else
6
+ STDOUT.puts 'You need to tell me what to watch!'
7
+ STDOUT.puts 'Usage:'
8
+ STDOUT.puts 'bin/cr somefile.rb'
9
+ Kernel.exit(true)
10
+ end
11
+
12
+ configFile = 'http://jsoxford.com/cr.json'
13
+ require_relative('../lib/coderetreat.rb')
14
+ config = ARGV.length >= 3 ? {host: ARGV[1], port: ARGV[2]} : CodeRetreatRunner.config(configFile)
15
+ CodeRetreatRunner.new.run(file, config)
@@ -0,0 +1,159 @@
1
+ # encoding: UTF-8
2
+ require 'socket'
3
+ require 'json'
4
+ require 'digest'
5
+ require 'active_support/core_ext/hash/indifferent_access'
6
+ require 'net/http'
7
+ require 'rspec'
8
+
9
+ class CodeRetreatRunner
10
+
11
+ def self.config(url)
12
+ JSON.parse(Net::HTTP.get(URI(url)))['endpoint'].with_indifferent_access
13
+ end
14
+
15
+ # Runs the runner
16
+ def run(filename, config)
17
+ STDOUT.puts "Watching #{filename}"
18
+
19
+ unless File.exists?(filename)
20
+ return STDOUT.puts 'Something went pretty badly wrong. Does that file exist?'
21
+ end
22
+
23
+ STDOUT.puts "Connecting to #{config[:host]}:#{config[:port]}"
24
+ connect(config)
25
+
26
+ # Receive data and check the test file indefinitely
27
+ loop do
28
+ test(filename) if changed(filename)
29
+ receive
30
+ end
31
+ end
32
+
33
+ # Runs the tests in the test file
34
+ def test(filename)
35
+ begin
36
+ RSpec.reset
37
+ config = RSpec.configuration
38
+ config.color = true
39
+
40
+ json_formatter = RSpec::Core::Formatters::JsonFormatter.new(config.output_stream)
41
+ reporter = RSpec::Core::Reporter.new(config)
42
+ reporter.register_listener(json_formatter, :message, :dump_summary, :stop)
43
+ config.instance_variable_set(:@reporter, reporter)
44
+
45
+ RSpec::Core::Runner.run([filename])
46
+ data = json_formatter.output_hash
47
+
48
+ setInterrupt
49
+
50
+ symbols = {passed: '✓', pending: '.', failed: '✖'}
51
+ STDOUT.puts data[:examples].map{ |example| ' ' + symbols[example[:status].to_sym] }.join('')
52
+
53
+ data[:examples].select{ |example| example[:status] == 'failed' }.map do |example|
54
+ STDOUT.puts "fail: #{example[:full_description]} -- error: #{example[:exception][:message]}"
55
+ end
56
+
57
+ send({
58
+ action: 'consumeTestResults',
59
+ payload: {
60
+ testsRun: data[:summary][:example_count],
61
+ testsFailed: data[:summary][:failure_count],
62
+ testsIgnored: data[:summary][:pending_count]
63
+ }
64
+ })
65
+
66
+ rescue Exception => e
67
+ STDOUT.puts "Failed to load your code, do you have errors in your Ruby? Exception: [#{e}]"
68
+ end
69
+ end
70
+
71
+ # Connects the TCP socket
72
+ def connect(config)
73
+ @client = TCPSocket.open config[:host], config[:port]
74
+ setInterrupt
75
+ end
76
+
77
+ # Disconnects the TCP socket
78
+ def disconnect
79
+ @client.close if @client
80
+ end
81
+
82
+ # Disable rspec interrupt, and disconnect our socket on close
83
+ def setInterrupt
84
+ Signal.trap('INT') do
85
+ disconnect
86
+ Kernel.exit(0)
87
+ end
88
+ end
89
+
90
+ # Sends JSON through the TCP socket
91
+ def send(data)
92
+ @client.write JSON.generate(data)
93
+ end
94
+
95
+ # Checks if the test file has changed (no more than once a second)
96
+ def changed(filename)
97
+ changed = false
98
+ now = Time.now.to_f
99
+
100
+ @timestamp ||= now
101
+ @fileHash ||= ''
102
+
103
+ if now - @timestamp > 1
104
+ File.open(filename, "r") do |file|
105
+ fileHash = Digest::SHA1.hexdigest(File.read(filename))
106
+ changed = fileHash != @fileHash
107
+ @fileHash = fileHash
108
+ end
109
+
110
+ @timestamp = now
111
+ end
112
+
113
+ changed
114
+ end
115
+
116
+ # Responds to a request
117
+ def respond(data)
118
+ payload = data[:payload]
119
+ success = false
120
+ message = nil
121
+
122
+ begin
123
+ case data[:action]
124
+ when 'tickBoard'
125
+ # CodeRetreat.tickBoard(payload[:result])
126
+ payload = {}
127
+ success = false
128
+ when 'tickCell'
129
+ payload[:generation]++
130
+ payload[:lives] = CodeRetreat.tickCell(payload[:result])
131
+ payload[:from] = payload[:result]
132
+ payload.delete(:result)
133
+ success = true
134
+ else
135
+ message = "I don't understand the action requested: #{data[:action]}"
136
+ end
137
+ rescue Exception => e
138
+ message = "Requested action had an error: #{data[:action]}"
139
+ end
140
+
141
+ send({ respondingTo: data[:action], success: success, message: message, payload: payload })
142
+ end
143
+
144
+ # Recieve data from the TCP socket and buffers into JSON objects
145
+ def receive
146
+ @buffer ||= ''
147
+ data = @client.recv(128)
148
+ unless data.nil?
149
+ @buffer += data
150
+
151
+ jsons = @buffer.split("\n")
152
+ jsons.each do |json|
153
+ respond(JSON.parse(json).with_indifferent_access) rescue nil
154
+ end
155
+
156
+ @buffer = jsons.last unless @buffer.match(/\n$/)
157
+ end
158
+ end
159
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: coderetreat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Pete West
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Automatically run your tests, and connect to the Code Retreat Game of
14
+ Life server to be part of the bigger picture
15
+ email: peterjwest3@gmail.com
16
+ executables:
17
+ - cr
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/cr
22
+ - lib/coderetreat.rb
23
+ homepage: https://github.com/jsoxford/code-retreat-rb
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.2.2
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Code Retreat Game of Life runner
47
+ test_files: []