voight_kampff 0.2.2 → 1.0.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -4
  3. data/README.md +75 -0
  4. data/config.ru +7 -0
  5. data/config/crawler-user-agents.json +750 -0
  6. data/lib/tasks/voight_kampff.rake +9 -7
  7. data/lib/voight_kampff.rb +3 -29
  8. data/lib/voight_kampff/engine.rb +0 -5
  9. data/lib/voight_kampff/rack_request.rb +11 -0
  10. data/lib/voight_kampff/test.rb +18 -59
  11. data/lib/voight_kampff/version.rb +1 -1
  12. data/spec/controllers/replicants_controller_spec.rb +31 -0
  13. data/spec/internal/app/controllers/replicants_controller.rb +13 -0
  14. data/spec/internal/config/routes.rb +4 -0
  15. data/spec/internal/log/.gitignore +1 -0
  16. data/{tests/test_app → spec/internal}/public/favicon.ico +0 -0
  17. data/spec/lib/voight_kampff/rack_request_spec.rb +33 -0
  18. data/spec/lib/voight_kampff/test_spec.rb +28 -0
  19. data/spec/lib/voight_kampff_spec.rb +27 -0
  20. data/spec/spec_helper.rb +11 -0
  21. data/spec/support/humans.rb +9 -0
  22. data/spec/support/replicants.rb +5 -0
  23. data/voight_kampff.gemspec +4 -5
  24. metadata +30 -70
  25. data/.autotest +0 -22
  26. data/CHANGELOG.rdoc +0 -16
  27. data/README.markdown +0 -63
  28. data/Rakefile +0 -20
  29. data/config/initializers/extend_action_dispatch_request.rb +0 -46
  30. data/config/user_agents.yml +0 -12438
  31. data/lib/voight_kampff/base.rb +0 -7
  32. data/lib/voight_kampff/user_agents_parser.rb +0 -54
  33. data/tests/spec/minitest_helper.rb +0 -2
  34. data/tests/spec/voight_kampff_spec.rb +0 -10
  35. data/tests/test_app/.gitignore +0 -15
  36. data/tests/test_app/Gemfile +0 -39
  37. data/tests/test_app/Rakefile +0 -7
  38. data/tests/test_app/app/controllers/application_controller.rb +0 -3
  39. data/tests/test_app/app/helpers/application_helper.rb +0 -2
  40. data/tests/test_app/app/mailers/.gitkeep +0 -0
  41. data/tests/test_app/app/models/.gitkeep +0 -0
  42. data/tests/test_app/app/views/layouts/application.html.erb +0 -14
  43. data/tests/test_app/config.ru +0 -4
  44. data/tests/test_app/config/application.rb +0 -62
  45. data/tests/test_app/config/boot.rb +0 -6
  46. data/tests/test_app/config/database.yml +0 -25
  47. data/tests/test_app/config/environment.rb +0 -5
  48. data/tests/test_app/config/environments/development.rb +0 -37
  49. data/tests/test_app/config/environments/production.rb +0 -67
  50. data/tests/test_app/config/environments/test.rb +0 -37
  51. data/tests/test_app/config/initializers/backtrace_silencers.rb +0 -7
  52. data/tests/test_app/config/initializers/inflections.rb +0 -15
  53. data/tests/test_app/config/initializers/mime_types.rb +0 -5
  54. data/tests/test_app/config/initializers/secret_token.rb +0 -7
  55. data/tests/test_app/config/initializers/session_store.rb +0 -8
  56. data/tests/test_app/config/initializers/wrap_parameters.rb +0 -14
  57. data/tests/test_app/config/locales/en.yml +0 -5
  58. data/tests/test_app/config/routes.rb +0 -58
  59. data/tests/test_app/lib/assets/.gitkeep +0 -0
  60. data/tests/test_app/lib/tasks/.gitkeep +0 -0
  61. data/tests/test_app/log/.gitkeep +0 -0
  62. data/tests/test_app/public/404.html +0 -26
  63. data/tests/test_app/public/422.html +0 -26
  64. data/tests/test_app/public/500.html +0 -25
  65. data/tests/test_app/public/index.html +0 -241
  66. data/tests/test_app/public/robots.txt +0 -5
  67. data/tests/test_app/script/rails +0 -6
  68. data/tests/test_app/test/fixtures/.gitkeep +0 -0
  69. data/tests/test_app/test/functional/.gitkeep +0 -0
  70. data/tests/test_app/test/integration/.gitkeep +0 -0
  71. data/tests/test_app/test/performance/browsing_test.rb +0 -12
  72. data/tests/test_app/test/test_helper.rb +0 -13
  73. data/tests/test_app/test/unit/.gitkeep +0 -0
  74. data/tests/test_app/vendor/assets/javascripts/.gitkeep +0 -0
  75. data/tests/test_app/vendor/assets/stylesheets/.gitkeep +0 -0
  76. data/tests/test_app/vendor/plugins/.gitkeep +0 -0
@@ -1,12 +1,14 @@
1
1
  namespace :voight_kampff do
2
-
3
- desc 'Import a new uesr_agents.yml file'
2
+ desc 'Import a new crawler-user-agents.json file'
4
3
  task :import_user_agents, :url do |t, args|
5
- args.with_defaults :url => 'http://www.user-agents.org/allagents.xml'
6
- agents = VoightKampff::UserAgentsParser.new(args[:url])
4
+ args.with_defaults url: 'https://raw.githubusercontent.com/monperrus/crawler-user-agents/master/crawler-user-agents.json'
7
5
 
8
- file = File.open(Rails.root.join('config','user_agents.yml'), 'w')
9
- file.write(agents.to_yaml)
10
- end
6
+ require 'net/http'
11
7
 
8
+ uri = URI(args[:url])
9
+ contents = Net::HTTP.get(uri)
10
+
11
+ file = File.open('./config/crawler-user-agents.json', 'w')
12
+ file.write(contents)
13
+ end
12
14
  end
data/lib/voight_kampff.rb CHANGED
@@ -1,11 +1,11 @@
1
+ require 'json'
2
+
1
3
  require 'voight_kampff/test'
2
- require 'voight_kampff/user_agents_parser'
4
+ require 'voight_kampff/rack_request'
3
5
  require 'voight_kampff/engine' if defined?(Rails)
4
6
 
5
7
  module VoightKampff
6
-
7
8
  class << self
8
-
9
9
  def root
10
10
  require 'pathname'
11
11
  Pathname.new File.expand_path '..', File.dirname(__FILE__)
@@ -20,36 +20,10 @@ module VoightKampff
20
20
  end
21
21
  alias :replicant? :bot?
22
22
 
23
- def browser?(user_agent_string)
24
- test(user_agent_string).browser?
25
- end
26
-
27
- def checker?(user_agent_string)
28
- test(user_agent_string).checker?
29
- end
30
-
31
- def downloader?(user_agent_string)
32
- test(user_agent_string).downloader?
33
- end
34
-
35
- def proxy?(user_agent_string)
36
- test(user_agent_string).proxy?
37
- end
38
-
39
- def crawler?(user_agent_string)
40
- test(user_agent_string).crawler?
41
- end
42
-
43
- def spam?(user_agent_string)
44
- test(user_agent_string).spam?
45
- end
46
-
47
23
  private
48
24
 
49
25
  def test(user_agent_string)
50
26
  VoightKampff::Test.new(user_agent_string)
51
27
  end
52
-
53
28
  end
54
-
55
29
  end
@@ -1,12 +1,7 @@
1
- require 'voight_kampff'
2
- require 'rails'
3
-
4
1
  module VoightKampff
5
2
  class Engine < Rails::Engine
6
-
7
3
  rake_tasks do
8
4
  load 'tasks/voight_kampff.rake'
9
5
  end
10
-
11
6
  end
12
7
  end
@@ -0,0 +1,11 @@
1
+ # Reopen the Rack::Request class to add bot detection methods
2
+ class Rack::Request
3
+ def human?
4
+ VoightKampff::Test.new(user_agent).human?
5
+ end
6
+
7
+ def bot?
8
+ VoightKampff::Test.new(user_agent).bot?
9
+ end
10
+ alias :replicant? :bot?
11
+ end
@@ -1,88 +1,47 @@
1
1
  module VoightKampff
2
-
3
2
  class Test
3
+ CRAWLERS_FILENAME = 'crawler-user-agents.json'
4
4
 
5
5
  attr_accessor :user_agent_string
6
- attr_accessor :types
7
6
 
8
7
  def initialize(user_agent_string)
9
- load_agents
10
8
  @user_agent_string = user_agent_string
11
- @types = Array(agent['types']).map(&:to_sym)
12
- @description = agent['description']
13
9
  end
14
10
 
15
11
  def agent
16
- @agent ||= @@agents.find do |agent|
17
- if agent['string_match'] == 'regex'
18
- @user_agent_string =~ Regexp.new(agent['string'], Regexp::IGNORECASE)
19
- else
20
- @user_agent_string.to_s.casecmp(agent['string'].to_s) == 0
21
- end
22
- end || {}
23
- end
12
+ load_crawlers
24
13
 
25
- def has_type?(*types)
26
- return nil if agent.empty?
27
-
28
- types.any? do |type|
29
- @types.include? type
30
- end
14
+ @agent ||= @@crawlers.find do |crawler|
15
+ user_agent_string =~ Regexp.new(crawler['pattern'], Regexp::IGNORECASE)
16
+ end || {}
31
17
  end
32
18
 
33
19
  def human?
34
- has_type? :browser, :downloader, :proxy
20
+ agent.empty?
35
21
  end
36
22
 
37
23
  def bot?
38
- has_type? :checker, :crawler, :spam
24
+ !human?
39
25
  end
40
26
  alias :replicant? :bot?
41
27
 
42
- def browser?
43
- has_type? :browser
44
- end
45
-
46
- def checker?
47
- has_type? :checker
48
- end
49
-
50
- def downloader?
51
- has_type? :downloader
52
- end
28
+ private
53
29
 
54
- def proxy?
55
- has_type? :proxy
56
- end
30
+ def lookup_paths
31
+ # These paths should be orderd by priority
32
+ base_paths = []
33
+ base_paths << Rails.root if defined? Rails
34
+ base_paths << VoightKampff.root
57
35
 
58
- def crawler?
59
- has_type? :crawler
36
+ base_paths.map { |p| p.join('config', CRAWLERS_FILENAME) }
60
37
  end
61
38
 
62
- def spam?
63
- has_type? :spam
39
+ def preferred_path
40
+ lookup_paths.find { |path| File.exists? path }
64
41
  end
65
42
 
66
- private
67
-
68
- def load_agents
69
- @@agents ||= []
70
- if @@agents.empty?
71
-
72
- base_paths = []
73
- base_paths << Rails.root if defined? Rails
74
- base_paths << VoightKampff.root
75
- rel_path = ['config', 'user_agents.yml']
76
-
77
- base_paths.any? do |base_path|
78
- if File.exists? base_path.join(*rel_path)
79
- @@agents = YAML.load(File.open(base_path.join(*rel_path), 'r'))
80
- end
81
- end
82
-
83
- end
43
+ def load_crawlers
44
+ @@crawlers ||= JSON.load(File.open(preferred_path, 'r'))
84
45
  end
85
-
86
46
  end
87
-
88
47
  end
@@ -1,3 +1,3 @@
1
1
  module VoightKampff
2
- VERSION = '0.2.2'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReplicantsController, type: :controller do
4
+ let(:user_agent_string) { '' }
5
+ before do
6
+ expect(request).to receive(:user_agent).and_return user_agent_string
7
+ get :index
8
+ end
9
+
10
+ HUMANS.each do |name, ua_string|
11
+ context "when user agent is #{name}" do
12
+ let(:user_agent_string) { ua_string }
13
+
14
+ it 'is forbidden' do
15
+ expect(response.status).to eql 403
16
+ expect(response.body).to match(/No replicants here/)
17
+ end
18
+ end
19
+ end
20
+
21
+ REPLICANTS.each do |name, ua_string|
22
+ context "when user agent is #{name}" do
23
+ let(:user_agent_string) { ua_string }
24
+
25
+ it 'is successful' do
26
+ expect(response.status).to eql 200
27
+ expect(response.body).to match(/Rick Deckard/)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ class ReplicantsController < ActionController::Base
2
+ def index
3
+ header = "Replicants:\n===========\n"
4
+
5
+ status, content = if request.bot?
6
+ [200, '- Rick Deckard']
7
+ else
8
+ [403, 'No replicants here']
9
+ end
10
+
11
+ render plain: header + content, status: status
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+ resources :replicants, only: :index
3
+ root to: 'replicants#index'
4
+ end
@@ -0,0 +1 @@
1
+ *.log
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::Request do
4
+ let(:user_agent_string) { }
5
+ let(:env) { {'HTTP_USER_AGENT' => user_agent_string} }
6
+ subject { Rack::Request.new(env) }
7
+
8
+ it { expect(subject).to respond_to :human? }
9
+ it { expect(subject).to respond_to :bot? }
10
+ it { expect(subject).to respond_to :replicant? }
11
+
12
+ HUMANS.each do |name, ua_string|
13
+ context "when user agent is #{name}" do
14
+ let(:user_agent_string) { ua_string }
15
+
16
+ it 'is not a replicant' do
17
+ expect(subject.human?).to eql true
18
+ expect(subject.bot?).to eql false
19
+ end
20
+ end
21
+ end
22
+
23
+ REPLICANTS.each do |name, ua_string|
24
+ context "when user agent is #{name}" do
25
+ let(:user_agent_string) { ua_string }
26
+
27
+ it 'is a replicant' do
28
+ expect(subject.bot?).to eql true
29
+ expect(subject.human?).to eql false
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe VoightKampff::Test do
4
+ let(:user_agent_string) { nil }
5
+ subject { VoightKampff::Test.new(user_agent_string) }
6
+
7
+ HUMANS.each do |name, ua_string|
8
+ context "when user agent is #{name}" do
9
+ let(:user_agent_string) { ua_string }
10
+
11
+ it 'is not a replicant' do
12
+ expect(subject.human?).to be true
13
+ expect(subject.bot?).to be false
14
+ end
15
+ end
16
+ end
17
+
18
+ REPLICANTS.each do |name, ua_string|
19
+ context "when user agent is #{name}" do
20
+ let(:user_agent_string) { ua_string }
21
+
22
+ it 'is a replicant' do
23
+ expect(subject.bot?).to be true
24
+ expect(subject.human?).to be false
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe VoightKampff do
4
+ subject { VoightKampff }
5
+
6
+ HUMANS.each do |name, ua_string|
7
+ context "when user agent is #{ua_string}" do
8
+ let(:user_agent_string) { ua_string }
9
+
10
+ it 'is not a replicant' do
11
+ expect(subject.human?(user_agent_string)).to be true
12
+ expect(subject.bot?(user_agent_string)).to be false
13
+ end
14
+ end
15
+ end
16
+
17
+ REPLICANTS.each do |name, ua_string|
18
+ context "when user agent is #{ua_string}" do
19
+ let(:user_agent_string) { ua_string }
20
+
21
+ it 'is a replicant' do
22
+ expect(subject.bot?(user_agent_string)).to be true
23
+ expect(subject.human?(user_agent_string)).to be false
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ require 'bundler/setup'
2
+ require 'combustion'
3
+ require 'voight_kampff'
4
+
5
+ Combustion.initialize! :action_controller
6
+
7
+ require 'rspec/rails'
8
+ Dir['./spec/support/**/*.rb'].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ end
@@ -0,0 +1,9 @@
1
+ HUMANS = {
2
+ 'Unknown' => nil, # for the moment we're treating a blank user agent string as not a bot
3
+ 'Chrome' => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
4
+ 'Firefox' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1',
5
+ 'Safari' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A',
6
+ 'Internet Explorer' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko',
7
+ 'Chrome Mobile' => 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19',
8
+ 'Safari for iOS' => 'Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53'
9
+ }
@@ -0,0 +1,5 @@
1
+ REPLICANTS = {
2
+ 'Googlebot' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
3
+ 'Bingbot' => 'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
4
+ 'Yahoo! Slurp' => 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)'
5
+ }
@@ -21,10 +21,9 @@ Gem::Specification.new do |s|
21
21
  s.test_files = `git ls-files -- {tests}/**/*`.split("\n")
22
22
  s.require_path = 'lib'
23
23
 
24
- s.add_dependency 'httpclient', '~> 2.2'
24
+ s.add_dependency 'rack', '~> 1.6'
25
25
 
26
- # Nokogiri 1.6.0 has dropped support for Ruby 1.8.7
27
- s.add_dependency 'nokogiri', (RUBY_VERSION.match("1.8.7") ? '1.5.10' : '~> 1.6')
28
- s.add_development_dependency 'minitest', '~> 4.7'
29
- s.add_development_dependency 'rdoc', '~> 2.4'
26
+ s.add_development_dependency 'rails', '~> 4.2'
27
+ s.add_development_dependency 'rspec-rails', '~> 3.3'
28
+ s.add_development_dependency 'combustion', '~> 0.5'
30
29
  end
metadata CHANGED
@@ -1,141 +1,101 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voight_kampff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Crownoble
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: httpclient
14
+ name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.2'
19
+ version: '1.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.2'
26
+ version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
- name: nokogiri
28
+ name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.6'
34
- type: :runtime
33
+ version: '4.2'
34
+ type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.6'
40
+ version: '4.2'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
42
+ name: rspec-rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '4.7'
47
+ version: '3.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '4.7'
54
+ version: '3.3'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rdoc
56
+ name: combustion
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '2.4'
61
+ version: '0.5'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '2.4'
68
+ version: '0.5'
69
69
  description: Voight-Kampff detects bots, spiders, crawlers and replicants
70
70
  email: adam@obledesign.com
71
71
  executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
- - ".autotest"
76
75
  - ".gitignore"
77
76
  - ".ruby-version"
78
- - CHANGELOG.rdoc
79
77
  - Gemfile
80
78
  - MIT-LICENSE
81
- - README.markdown
82
- - Rakefile
83
- - config/initializers/extend_action_dispatch_request.rb
84
- - config/user_agents.yml
79
+ - README.md
80
+ - config.ru
81
+ - config/crawler-user-agents.json
85
82
  - lib/tasks/voight_kampff.rake
86
83
  - lib/voight_kampff.rb
87
- - lib/voight_kampff/base.rb
88
84
  - lib/voight_kampff/engine.rb
85
+ - lib/voight_kampff/rack_request.rb
89
86
  - lib/voight_kampff/test.rb
90
- - lib/voight_kampff/user_agents_parser.rb
91
87
  - lib/voight_kampff/version.rb
92
- - tests/spec/minitest_helper.rb
93
- - tests/spec/voight_kampff_spec.rb
94
- - tests/test_app/.gitignore
95
- - tests/test_app/Gemfile
96
- - tests/test_app/Gemfile.lock
97
- - tests/test_app/Rakefile
98
- - tests/test_app/app/controllers/application_controller.rb
99
- - tests/test_app/app/helpers/application_helper.rb
100
- - tests/test_app/app/mailers/.gitkeep
101
- - tests/test_app/app/models/.gitkeep
102
- - tests/test_app/app/views/layouts/application.html.erb
103
- - tests/test_app/config.ru
104
- - tests/test_app/config/application.rb
105
- - tests/test_app/config/boot.rb
106
- - tests/test_app/config/database.yml
107
- - tests/test_app/config/environment.rb
108
- - tests/test_app/config/environments/development.rb
109
- - tests/test_app/config/environments/production.rb
110
- - tests/test_app/config/environments/test.rb
111
- - tests/test_app/config/initializers/backtrace_silencers.rb
112
- - tests/test_app/config/initializers/inflections.rb
113
- - tests/test_app/config/initializers/mime_types.rb
114
- - tests/test_app/config/initializers/secret_token.rb
115
- - tests/test_app/config/initializers/session_store.rb
116
- - tests/test_app/config/initializers/wrap_parameters.rb
117
- - tests/test_app/config/locales/en.yml
118
- - tests/test_app/config/routes.rb
119
- - tests/test_app/doc/README_FOR_APP
120
- - tests/test_app/lib/assets/.gitkeep
121
- - tests/test_app/lib/tasks/.gitkeep
122
- - tests/test_app/log/.gitkeep
123
- - tests/test_app/public/404.html
124
- - tests/test_app/public/422.html
125
- - tests/test_app/public/500.html
126
- - tests/test_app/public/favicon.ico
127
- - tests/test_app/public/index.html
128
- - tests/test_app/public/robots.txt
129
- - tests/test_app/script/rails
130
- - tests/test_app/test/fixtures/.gitkeep
131
- - tests/test_app/test/functional/.gitkeep
132
- - tests/test_app/test/integration/.gitkeep
133
- - tests/test_app/test/performance/browsing_test.rb
134
- - tests/test_app/test/test_helper.rb
135
- - tests/test_app/test/unit/.gitkeep
136
- - tests/test_app/vendor/assets/javascripts/.gitkeep
137
- - tests/test_app/vendor/assets/stylesheets/.gitkeep
138
- - tests/test_app/vendor/plugins/.gitkeep
88
+ - spec/controllers/replicants_controller_spec.rb
89
+ - spec/internal/app/controllers/replicants_controller.rb
90
+ - spec/internal/config/routes.rb
91
+ - spec/internal/log/.gitignore
92
+ - spec/internal/public/favicon.ico
93
+ - spec/lib/voight_kampff/rack_request_spec.rb
94
+ - spec/lib/voight_kampff/test_spec.rb
95
+ - spec/lib/voight_kampff_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/support/humans.rb
98
+ - spec/support/replicants.rb
139
99
  - voight_kampff.gemspec
140
100
  homepage: https://github.com/biola/Voight-Kampff
141
101
  licenses: