gatherable 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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +6 -0
  4. data/app/assets/javascripts/gatherable/application.js +13 -0
  5. data/app/controllers/gatherable/application_controller.rb +43 -0
  6. data/app/models/data_point.rb +28 -0
  7. data/app/writers/controller_writer.rb +34 -0
  8. data/app/writers/migration_writer.rb +90 -0
  9. data/app/writers/model_writer.rb +36 -0
  10. data/config/routes.rb +2 -0
  11. data/lib/gatherable.rb +41 -0
  12. data/lib/gatherable/configuration.rb +19 -0
  13. data/lib/gatherable/engine.rb +5 -0
  14. data/lib/gatherable/version.rb +3 -0
  15. data/lib/generators/gatherable/USAGE +32 -0
  16. data/lib/generators/gatherable/gatherable_generator.rb +33 -0
  17. data/lib/generators/gatherable/templates/application_controller.rb +43 -0
  18. data/lib/generators/gatherable/templates/gatherable.rb +9 -0
  19. data/lib/tasks/db_tasks.rake +14 -0
  20. data/lib/tasks/gatherable_tasks.rake +6 -0
  21. data/lib/version.rb +3 -0
  22. data/spec/controllers/gatherable/application_controller_spec.rb +110 -0
  23. data/spec/dummy/Rakefile +6 -0
  24. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  25. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  26. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  27. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/spec/dummy/bin/bundle +3 -0
  29. data/spec/dummy/bin/rails +4 -0
  30. data/spec/dummy/bin/rake +4 -0
  31. data/spec/dummy/bin/setup +29 -0
  32. data/spec/dummy/config.ru +4 -0
  33. data/spec/dummy/config/application.rb +26 -0
  34. data/spec/dummy/config/boot.rb +5 -0
  35. data/spec/dummy/config/database.yml +11 -0
  36. data/spec/dummy/config/database.yml.travis +4 -0
  37. data/spec/dummy/config/environment.rb +5 -0
  38. data/spec/dummy/config/environments/development.rb +41 -0
  39. data/spec/dummy/config/environments/production.rb +79 -0
  40. data/spec/dummy/config/environments/test.rb +42 -0
  41. data/spec/dummy/config/initializers/assets.rb +11 -0
  42. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  44. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  45. data/spec/dummy/config/initializers/inflections.rb +16 -0
  46. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  47. data/spec/dummy/config/initializers/session_store.rb +3 -0
  48. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  49. data/spec/dummy/config/locales/en.yml +23 -0
  50. data/spec/dummy/config/routes.rb +3 -0
  51. data/spec/dummy/config/secrets.yml +5 -0
  52. data/spec/dummy/log/test.log +1550 -0
  53. data/spec/dummy/public/404.html +67 -0
  54. data/spec/dummy/public/422.html +67 -0
  55. data/spec/dummy/public/500.html +66 -0
  56. data/spec/dummy/public/favicon.ico +0 -0
  57. data/spec/lib/gatherable_spec.rb +88 -0
  58. data/spec/lib/generators/gatherable_generator_spec.rb +107 -0
  59. data/spec/models/data_point_spec.rb +44 -0
  60. data/spec/rails_helper.rb +57 -0
  61. data/spec/spec_helper.rb +92 -0
  62. metadata +243 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
@@ -0,0 +1,88 @@
1
+ require 'rails_helper'
2
+ require "gatherable/configuration"
3
+
4
+ describe Gatherable do
5
+ describe '#configuration' do
6
+ context 'data points' do
7
+ it 'saves data points' do
8
+ expect(Gatherable.config.data_points.count).to eql 1
9
+ end
10
+
11
+ it 'saves data points with correct attributes' do
12
+ expect(Gatherable.config.data_points.first.data_type).to eql :decimal
13
+ expect(Gatherable.config.data_points.first.name).to eql :price
14
+ end
15
+ end
16
+
17
+ it 'saves global identifier' do
18
+ expect(Gatherable.config.global_identifier).to eql :session_id
19
+ end
20
+ end
21
+
22
+ describe '#configure' do
23
+ context 'already configured' do
24
+ it 'does not change config' do
25
+ expect(Gatherable).to_not receive(:create_models)
26
+ expect(Gatherable).to_not receive(:create_controllers)
27
+ expect(Gatherable).to_not receive(:create_routes)
28
+ Gatherable.configure { |c| c.data_point :foo, :bar }
29
+ end
30
+ end
31
+
32
+ it 'creates model classes' do
33
+ expect(Object.const_defined?('Gatherable::Price')).to be true
34
+ end
35
+
36
+ specify 'model classes have correct table names' do
37
+ expect(Gatherable::Price.table_name).to eql 'prices'
38
+ end
39
+
40
+ specify "model classes are prefixed with 'gatherable'" do
41
+ expect(Gatherable::Price.table_name_prefix).to eql 'gatherable.'
42
+ end
43
+
44
+ it 'creates controllers' do
45
+ expect(Object.const_defined?('Gatherable::PricesController')).to be true
46
+ end
47
+
48
+ context 'routes' do
49
+ let(:routes) { Gatherable::Engine.routes.routes }
50
+
51
+ it 'prefixes route with global identifier' do
52
+ routes.each do |r|
53
+ expect(r.path.spec.to_s).to match(/^\/:session_id\//)
54
+ end
55
+ end
56
+
57
+ it 'creates named paths' do
58
+ routes.each do |r|
59
+ expect(r.name).to match(/price/)
60
+ end
61
+ end
62
+
63
+ context 'POST route' do
64
+ let(:post_route) { routes.first }
65
+
66
+ it 'creates a POST route' do
67
+ expect(post_route.verb).to eql(/^POST$/)
68
+ end
69
+
70
+ it 'creates the correct path' do
71
+ expect(post_route.path.spec.to_s).to eql '/:session_id/prices(.:format)'
72
+ end
73
+ end
74
+
75
+ context 'GET route' do
76
+ let(:get_route) { routes.last }
77
+
78
+ it 'creates a GET route' do
79
+ expect(get_route.verb).to eql(/^GET$/)
80
+ end
81
+
82
+ it 'creates the correct path' do
83
+ expect(get_route.path.spec.to_s).to eql '/:session_id/prices/:price_id(.:format)'
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,107 @@
1
+ require 'rails_helper'
2
+ require 'generators/gatherable/gatherable_generator'
3
+
4
+ describe GatherableGenerator, :type => :generator do
5
+ let(:file_stream) { IO.new(0) }
6
+
7
+ it 'creates initializer' do
8
+ generator = described_class.new(['initializer'])
9
+ allow(described_class).to receive(:new) { generator }
10
+ expect(generator).to receive(:copy_file).with('gatherable.rb', 'config/initializers/gatherable.rb')
11
+ Rails::Generators.invoke('gatherable', ['initializer'])
12
+ end
13
+
14
+
15
+ shared_examples_for 'creating a file' do
16
+ let!(:generator) { described_class.new([generator_target]) }
17
+
18
+ before do
19
+ allow(described_class).to receive(:new) { generator }
20
+ allow(generator).to receive(:copy_file)
21
+ end
22
+
23
+ context 'setup' do
24
+ it 'creates the destination directory' do
25
+ allow(File).to receive(:open).with(output_file, 'w')
26
+ expect(FileUtils).to receive(:mkdir_p).with(file_destination)
27
+ Rails::Generators.invoke('gatherable', [generator_target])
28
+ end
29
+ end
30
+
31
+ context 'for data points' do
32
+ before do
33
+ allow(FileUtils).to receive(:mkdir_p).with(file_destination)
34
+ end
35
+
36
+ it 'creates the output file' do
37
+ expect(File).to receive(:open).with(output_file, 'w')
38
+ Rails::Generators.invoke('gatherable', [generator_target])
39
+ end
40
+
41
+ it 'correctly writes to the file' do
42
+ allow(File).to receive(:open).with(output_file, 'w').and_yield(file_stream)
43
+ expect(file_stream).to receive(:puts).with(file_content)
44
+ Rails::Generators.invoke('gatherable', [generator_target])
45
+ end
46
+
47
+ it 'notifies the user of file creation' do
48
+ allow(File).to receive(:open).with(output_file, 'w')
49
+ allow(File).to receive(:exists?).with(output_file).and_return(false, true)
50
+ expect{Rails::Generators.invoke('gatherable', [generator_target])}.to \
51
+ output("created #{output_file}\n").to_stdout
52
+ end
53
+
54
+ it 'notifies the user if file already exists' do
55
+ allow(File).to receive(:open).with(output_file, 'w')
56
+ allow(File).to receive(:exists?).with(output_file) { true }
57
+ allow(Dir).to receive(:[]) { 'a_matching_file' }
58
+ expect{Rails::Generators.invoke('gatherable', [generator_target])}.to \
59
+ output(/Skipping/).to_stdout
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'controllers' do
65
+ let(:output_file) { File.join(Rails.root, 'app/controllers/gatherable/prices_controller.rb') }
66
+ let(:file_destination) { 'app/controllers/gatherable' }
67
+ let(:file_content) do
68
+ <<-controller
69
+ module Gatherable
70
+ class PricesController < Gatherable::ApplicationController
71
+ end
72
+ end
73
+ controller
74
+ end
75
+ let(:generator_target) { 'controllers' }
76
+ it_behaves_like 'creating a file'
77
+
78
+ let!(:generator) { described_class.new([generator_target]) }
79
+
80
+ before { allow(described_class).to receive(:new) { generator } }
81
+
82
+ context 'setup' do
83
+ it 'copies application controller' do
84
+ allow(Gatherable.config).to receive(:data_points) { [] }
85
+ expect(generator).to receive(:copy_file).with('application_controller.rb', 'app/controllers/gatherable/application_controller.rb')
86
+ Rails::Generators.invoke('gatherable', ['controllers'])
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'models' do
92
+ let(:output_file) { File.join(Rails.root, 'app/models/gatherable/price.rb') }
93
+ let(:file_destination) { 'app/models/gatherable' }
94
+ let(:file_content) do
95
+ <<-content
96
+ module Gatherable
97
+ class Price < ActiveRecord::Base
98
+ self.table_name = 'prices'
99
+ self.table_name_prefix = 'gatherable.'
100
+ end
101
+ end
102
+ content
103
+ end
104
+ let(:generator_target) { 'models' }
105
+ it_behaves_like 'creating a file'
106
+ end
107
+ end
@@ -0,0 +1,44 @@
1
+ require 'rails_helper'
2
+
3
+ module Gatherable
4
+ describe DataPoint do
5
+ subject(:data_point) { described_class.new(:price, :decimal) }
6
+ context 'generating models' do
7
+ before { subject.classify }
8
+ it 'creates the model class' do
9
+ expect(Object.const_defined?('Gatherable::Price')).to be true
10
+ end
11
+
12
+ it 'inherits from ActiveRecord::Base' do
13
+ expect(Gatherable::Price.superclass).to be ActiveRecord::Base
14
+ end
15
+ end
16
+
17
+ context 'generating controllers' do
18
+ before { subject.controllerify}
19
+ it 'creates the controller class' do
20
+ expect(Object.const_defined?('Gatherable::PricesController')).to be true
21
+ end
22
+
23
+ it 'inherits from Gatherable::ApplicationController' do
24
+ expect(Gatherable::PricesController.superclass).to be Gatherable::ApplicationController
25
+ end
26
+ end
27
+
28
+ #TODO: move these
29
+ =begin
30
+ before do
31
+ Gatherable.configure do |config|
32
+ config.data_point :price, :decimal
33
+ end
34
+ end
35
+ it 'indexes the global_identifier' do
36
+
37
+ end
38
+
39
+ it 'prefixes the primary key with the class name' do
40
+
41
+ end
42
+ =end
43
+ end
44
+ end