ember_serialize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/lib/ember_serialize.rb +245 -0
  5. data/lib/ember_serialize/version.rb +3 -0
  6. data/lib/tasks/ember_serialize_tasks.rake +8 -0
  7. data/test/ci.sh +3 -0
  8. data/test/dummy/README.rdoc +28 -0
  9. data/test/dummy/Rakefile +6 -0
  10. data/test/dummy/app/assets/javascripts/application.js.coffee +15 -0
  11. data/test/dummy/app/assets/javascripts/models/comment.js.coffee +11 -0
  12. data/test/dummy/app/assets/javascripts/models/default/comment.js.coffee +11 -0
  13. data/test/dummy/app/assets/javascripts/models/default/post.js.coffee +11 -0
  14. data/test/dummy/app/assets/javascripts/models/default/user.js.coffee +8 -0
  15. data/test/dummy/app/assets/javascripts/models/post.js.coffee +11 -0
  16. data/test/dummy/app/assets/javascripts/models/tests/as_is.js.coffee +11 -0
  17. data/test/dummy/app/assets/javascripts/models/tests/async.js.coffee +9 -0
  18. data/test/dummy/app/assets/javascripts/models/tests/find_existing.js.coffee +11 -0
  19. data/test/dummy/app/assets/javascripts/models/tests/ignore.js.coffee +10 -0
  20. data/test/dummy/app/assets/javascripts/models/tests/ignore_outside.js.coffee +11 -0
  21. data/test/dummy/app/assets/javascripts/models/user.js.coffee +8 -0
  22. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  23. data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
  24. data/test/dummy/app/controllers/application_controller.rb +5 -0
  25. data/test/dummy/app/controllers/comments_controller.rb +7 -0
  26. data/test/dummy/app/controllers/posts_controller.rb +7 -0
  27. data/test/dummy/app/controllers/users_controller.rb +7 -0
  28. data/test/dummy/app/helpers/application_helper.rb +2 -0
  29. data/test/dummy/app/models/comment.rb +4 -0
  30. data/test/dummy/app/models/post.rb +4 -0
  31. data/test/dummy/app/models/user.rb +4 -0
  32. data/test/dummy/app/serializers/comment_serializer.rb +4 -0
  33. data/test/dummy/app/serializers/post_serializer.rb +5 -0
  34. data/test/dummy/app/serializers/user_serializer.rb +3 -0
  35. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  36. data/test/dummy/bin/bundle +3 -0
  37. data/test/dummy/bin/rails +4 -0
  38. data/test/dummy/bin/rake +4 -0
  39. data/test/dummy/config.ru +4 -0
  40. data/test/dummy/config/application.rb +23 -0
  41. data/test/dummy/config/boot.rb +5 -0
  42. data/test/dummy/config/database.yml +25 -0
  43. data/test/dummy/config/environment.rb +5 -0
  44. data/test/dummy/config/environments/development.rb +37 -0
  45. data/test/dummy/config/environments/production.rb +82 -0
  46. data/test/dummy/config/environments/test.rb +39 -0
  47. data/test/dummy/config/initializers/assets.rb +8 -0
  48. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  50. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  51. data/test/dummy/config/initializers/inflections.rb +16 -0
  52. data/test/dummy/config/initializers/mime_types.rb +4 -0
  53. data/test/dummy/config/initializers/session_store.rb +3 -0
  54. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/test/dummy/config/locales/en.yml +23 -0
  56. data/test/dummy/config/routes.rb +9 -0
  57. data/test/dummy/config/secrets.yml +22 -0
  58. data/test/dummy/db/development.sqlite3 +0 -0
  59. data/test/dummy/db/migrate/20140825151402_create_users.rb +9 -0
  60. data/test/dummy/db/migrate/20140825151509_create_posts.rb +11 -0
  61. data/test/dummy/db/migrate/20140825151605_create_comments.rb +12 -0
  62. data/test/dummy/db/schema.rb +39 -0
  63. data/test/dummy/db/test.sqlite3 +0 -0
  64. data/test/dummy/lib/tasks/ember_serialize_tasks.rake +8 -0
  65. data/test/dummy/log/development.log +153 -0
  66. data/test/dummy/log/test.log +8743 -0
  67. data/test/dummy/public/404.html +67 -0
  68. data/test/dummy/public/422.html +67 -0
  69. data/test/dummy/public/500.html +66 -0
  70. data/test/dummy/public/favicon.ico +0 -0
  71. data/test/dummy/tmp/ember-rails/ember-data.js +12053 -0
  72. data/test/dummy/tmp/ember-rails/ember.js +46762 -0
  73. data/test/ember_serialize_test.rb +225 -0
  74. data/test/test_helper.rb +21 -0
  75. metadata +270 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 30a32a6e4a585866dabaca1799635071eae2f590
4
+ data.tar.gz: 3bb6151fb3723cf2e66a3d63ac640742cfc3f2e8
5
+ SHA512:
6
+ metadata.gz: 86380a02c9dc2e59baa4f4501420521bb3aec9bf3fee9da24d3f360666fa6f3dc245b1f80b04133028948191653e30e30890b0e616b1469ae15fb682345b9bac
7
+ data.tar.gz: 89eaf0f0a532313f7f5e3cfbb35044cb063f7fe38848dd82c40d21ffac40437682d656c9f4612e42b918aa8fbc7659dee21795606666182262bf52bb8706b14a
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'EmberSerialize'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,245 @@
1
+ module EmberSerialize
2
+ class Serializer
3
+ class << self
4
+ attr_accessor :javascripts_dir, :models_dir
5
+ end
6
+
7
+ attr_accessor :args, :est, :een, :eig, :eai, :eas, :missing, :force_async, :javascripts_dir, :models_dir, :extension
8
+
9
+ def initialize(args)
10
+ @args = args
11
+ # args
12
+ @missing = args.extras.include?(':create') ? :create : :skip
13
+ @force_async = args.extras.grep(/^async\:/) {|e| e =~ /true/}.first ? true : false
14
+ # variables
15
+ @est = "ember_serialize:start"
16
+ @een = "ember_serialize:end"
17
+ @eig = "ember_serialize:ignore"
18
+ @eai = "ember_serialize:as_is"
19
+ @eas = "ember_serialize:async"
20
+ @javascripts_dir = self.class.javascripts_dir || "app/assets/javascripts/"
21
+ @models_dir = self.class.models_dir || @javascripts_dir+"models/"
22
+ unless File.exists? @models_dir
23
+ require 'fileutils'
24
+ FileUtils.mkdir_p @models_dir
25
+ end
26
+ # engine / extension
27
+ engine = args.extras.grep(/^engine\:/) {|e| e.gsub(/^.*:/,'').to_sym}.first
28
+ if engine == :coffee
29
+ @extension = ".js.coffee"
30
+ elsif engine == :em
31
+ @extension = ".js.em"
32
+ else
33
+ @extension = detect_extension
34
+ end
35
+ end
36
+
37
+ def serialize(match = nil)
38
+ # populate Rails descendants
39
+ Rails.application.eager_load!
40
+
41
+ # loop through serializers
42
+ ActiveModel::Serializer.descendants.sort_by(&:name).each do |serializer|
43
+ if match
44
+ next unless serializer.name =~ /#{match}/
45
+ end
46
+ schema = schema serializer
47
+ model = model_class serializer
48
+ ember_model_file = @models_dir + model.table_name.singularize + @extension
49
+ new_content = ember_model_build(schema, model, ember_model_parse(ember_model_file, model))
50
+ if new_content
51
+ File.write ember_model_file, new_content
52
+ end
53
+ end
54
+ end
55
+
56
+ def detect_extension
57
+ Dir[@models_dir+"*js.em"].blank? ? ".js.coffee" : ".js.em"
58
+ end
59
+
60
+ def camel(name)
61
+ name.to_s.underscore.camelize(:lower)
62
+ end
63
+
64
+ def ember_app_name(javascripts_dir = @javascripts_dir)
65
+ @app_name ||= begin
66
+ appname = Dir[javascripts_dir+"*"].select do |f|
67
+ File.file?(f)
68
+ end.map do |f|
69
+ open(f) do |f|
70
+ f.each_line.detect do |l|
71
+ /Ember.Application.create/.match(l)
72
+ end
73
+ end
74
+ end.compact.first.strip.gsub /.*window\.(\w+) =.*$/, '\1'
75
+ end
76
+ end
77
+
78
+ def ember_model(app_name, model, indent, extension)
79
+ klass = if extension == '.js.em'
80
+ "class #{app_name}.#{model.name} extends DS.Model"
81
+ else
82
+ "#{app_name}.#{model.name} = DS.Model.extend"
83
+ end
84
+ lines = <<MODEL
85
+ # for more details see: http://emberjs.com/guides/models/defining-models/
86
+
87
+ #{klass}
88
+ #{indent}# ember_serialize:start
89
+ #{indent}# ember_serialize:end
90
+ MODEL
91
+ lines.split /\n/
92
+ end
93
+
94
+ def ember_reflect(model, name, rel, async, existing, indent, type = 'string')
95
+ foreign_name = name.to_s.gsub(/_id$/, '').to_sym
96
+ _async = async ? ", {async: true}" : ''
97
+ assoc = model.reflect_on_all_associations.select do |a|
98
+ a.name == foreign_name && a.macro == rel.to_sym
99
+ end.first
100
+ camel_name = camel(name)
101
+ line = if assoc
102
+ if rel == :belongs_to || rel == :has_one
103
+ camel_name = camel(foreign_name)
104
+ if existing[camel_name].to_s =~ /belongsTo/
105
+ existing[camel_name]
106
+ else
107
+ assoc_name = assoc.table_name.singularize
108
+ "#{indent}#{camel_name}: DS.belongsTo('#{assoc_name}'#{_async})"
109
+ end
110
+ else
111
+ if existing[camel_name].to_s =~ /hasMany/
112
+ existing[camel_name]
113
+ else
114
+ "#{indent}#{camel_name}: DS.hasMany('#{camel_name}'#{_async})"
115
+ end
116
+ end
117
+ else
118
+ existing[camel_name] || "#{indent}#{camel_name}: DS.attr('#{type}')"
119
+ end
120
+ [camel_name, line]
121
+ end
122
+
123
+ def ember_model_parse(ember_model_file, model)
124
+ if !File.exists? ember_model_file
125
+ if @missing == :create
126
+ # create default file
127
+ lines = ember_model ember_app_name, model, " ", @extension
128
+ else
129
+ return nil
130
+ end
131
+ else
132
+ lines = File.readlines(ember_model_file).map(&:rstrip)
133
+ end
134
+
135
+ # find start/end markers
136
+ line_start = lines.index {|l| l =~ /#{@est}/}
137
+ line_end = lines.index {|l| l =~ /#{@een}/}
138
+
139
+ if line_start && line_end
140
+ # find settings for ignore, as_is, and async
141
+ ignore = lines.grep(/#{@eig}/) do |l|
142
+ l.gsub(/.*#{@eig} (.*)\s*$/, '\1').split(/\s*,\s*/)
143
+ end.flatten.uniq.map {|t| camel(t)}
144
+ as_is = lines.grep(/#{@eai}/) do |l|
145
+ l.gsub(/.*#{@eai} (.*)\s*$/, '\1').split(/\s*,\s*/)
146
+ end.flatten.uniq.map {|t| camel(t)}
147
+ if @force_async.nil?
148
+ async = lines.grep(/#{@eas}/) do |l|
149
+ l.gsub(/.*#{@eai} (.*)\s*$/, '\1') == 'true'
150
+ end.flatten.last
151
+ async = true if async.nil?
152
+ else
153
+ async = @force_async
154
+ end
155
+
156
+ # match the indent of the start line
157
+ indent = lines[line_start][/\A */]
158
+
159
+ # catalog existing lines
160
+ existing = {}
161
+ lines.each_with_index do |line, i|
162
+ next if line =~ /^\s*#/ # reject comments
163
+ next unless line =~ /:\s*DS\./ #include DS lines
164
+ # reformat the line
165
+ name, ds = line.strip.gsub(/,$/,'').split(/:\s*/,2)
166
+ name = camel name
167
+ # save lines inside range as existing
168
+ if i > line_start && i < line_end
169
+ existing[name] = "#{indent}#{name}: #{ds}"
170
+ else # ignore ones outside the range
171
+ ignore << name
172
+ end
173
+ end
174
+ [lines, line_start, line_end, existing, ignore.uniq, as_is, async, indent]
175
+ else
176
+ nil
177
+ end
178
+ end
179
+
180
+ def ember_model_build(schema, model, args)
181
+ return nil unless args && args.length == 8
182
+ lines, line_start, line_end, existing, ignore, as_is, async, indent = args
183
+ new_lines = []
184
+
185
+ # build attributes
186
+ schema[:attributes].each do |name,type|
187
+ camel_name, line = if name =~ /_id$/ &&
188
+ type == :integer &&
189
+ !as_is.include?(name) &&
190
+ !as_is.include?(camel(name))
191
+ ember_reflect(model, name, :belongs_to, async, existing, indent, type)
192
+ else
193
+ ember_reflect(model, name, :attribute, async, existing, indent, type)
194
+ end
195
+ unless ignore.include? camel_name
196
+ new_lines << line
197
+ end
198
+ end
199
+
200
+ # build associations
201
+ schema[:associations].each do |key, assoc|
202
+ next if assoc.nil?
203
+ rel, table = assoc.flatten
204
+ camel_name, line = ember_reflect(model, table, rel, async, existing, indent)
205
+ unless ignore.include? camel_name
206
+ new_lines << line
207
+ end
208
+ end
209
+
210
+ # build final content
211
+ content = [ lines[0..line_start].join("\n") ]
212
+ unless ignore.blank?
213
+ content << "#{indent}# #{@eig} #{ignore.join(", ")}"
214
+ end
215
+ unless as_is.blank?
216
+ content << "#{indent}# #{@eai} #{as_is.join(", ")}"
217
+ end
218
+ if async == false
219
+ content << "#{indent}# #{@eas} false"
220
+ end
221
+ content << new_lines.join(",\n")
222
+ content << lines[line_end..-1].join("\n")
223
+
224
+ content.join("\n")
225
+ end
226
+
227
+ def model_class(serializer)
228
+ if serializer.respond_to? :model_class
229
+ return serializer.model_class
230
+ end
231
+ @model_classes ||= Hash.new do |h,k|
232
+ h[k] = k.name.gsub(/Serializer$/,'').constantize
233
+ end
234
+ @model_classes[serializer]
235
+ end
236
+
237
+ def schema(serializer)
238
+ if serializer.respond_to? :schema
239
+ serializer.schema
240
+ else
241
+ {}
242
+ end
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,3 @@
1
+ module EmberSerialize
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ namespace :db do
2
+ namespace :schema do
3
+ desc 'Regenerate Ember models from ActiveModel::Serializers'
4
+ task :ember => :environment do |task, args|
5
+ EmberSerialize::Serializer.new(args).serialize
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ cd test/dummy && bundle install --without debug && bundle exec rake db:create && bundle exec rake db:migrate && cd ../../ && bundle exec rake
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
14
+
15
+ window.EmberSerialize = Ember.Application.create
@@ -0,0 +1,11 @@
1
+ # for more details see: http://emberjs.com/guides/models/defining-models/
2
+
3
+ EmberSerialize.Comment = DS.Model.extend
4
+ # ember_serialize:start
5
+ # ember_serialize:async false
6
+ id: DS.attr('integer'),
7
+ title: DS.attr('string'),
8
+ body: DS.attr('text'),
9
+ author: DS.belongsTo('user'),
10
+ post: DS.belongsTo('post')
11
+ # ember_serialize:end
@@ -0,0 +1,11 @@
1
+ # for more details see: http://emberjs.com/guides/models/defining-models/
2
+
3
+ EmberSerialize.Comment = DS.Model.extend
4
+ # ember_serialize:start
5
+ # ember_serialize:async false
6
+ id: DS.attr('integer'),
7
+ title: DS.attr('string'),
8
+ body: DS.attr('text'),
9
+ author: DS.belongsTo('user'),
10
+ post: DS.belongsTo('post')
11
+ # ember_serialize:end
@@ -0,0 +1,11 @@
1
+ # for more details see: http://emberjs.com/guides/models/defining-models/
2
+
3
+ EmberSerialize.Post = DS.Model.extend
4
+ # ember_serialize:start
5
+ # ember_serialize:async false
6
+ id: DS.attr('integer'),
7
+ title: DS.attr('string'),
8
+ body: DS.attr('text'),
9
+ authorDude: DS.belongsTo('user'),
10
+ comments: DS.hasMany('comments')
11
+ # ember_serialize:end
@@ -0,0 +1,8 @@
1
+ # for more details see: http://emberjs.com/guides/models/defining-models/
2
+
3
+ EmberSerialize.User = DS.Model.extend
4
+ # ember_serialize:start
5
+ # ember_serialize:async false
6
+ id: DS.attr('integer'),
7
+ name: DS.attr('string')
8
+ # ember_serialize:end
@@ -0,0 +1,11 @@
1
+ # for more details see: http://emberjs.com/guides/models/defining-models/
2
+
3
+ EmberSerialize.Post = DS.Model.extend
4
+ # ember_serialize:start
5
+ # ember_serialize:async false
6
+ id: DS.attr('integer'),
7
+ title: DS.attr('string'),
8
+ body: DS.attr('text'),
9
+ authorDude: DS.belongsTo('user'),
10
+ comments: DS.hasMany('comments')
11
+ # ember_serialize:end
@@ -0,0 +1,11 @@
1
+ # for more details see: http://emberjs.com/guides/models/defining-models/
2
+
3
+ EmberSerialize.Comment = DS.Model.extend
4
+ # ember_serialize:start
5
+ # ember_serialize:as_is post_id
6
+ id: DS.attr('integer'),
7
+ title: DS.attr('string'),
8
+ body: DS.attr('text'),
9
+ author: DS.belongsTo('user'),
10
+ post: DS.belongsTo('post')
11
+ # ember_serialize:end