the_sortable_tree 1.9.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/MIT-LICENSE +4 -2
  2. data/README.md +237 -438
  3. data/app/assets/images/iconza/{gray → icons}/add.png +0 -0
  4. data/app/assets/images/iconza/{gray → icons}/delete.png +0 -0
  5. data/app/assets/images/iconza/{gray → icons}/edit.png +0 -0
  6. data/app/assets/images/iconza/icons/move.png +0 -0
  7. data/app/assets/images/iconza/{red/add.png → icons/red_add.png} +0 -0
  8. data/app/assets/images/iconza/{red/delete.png → icons/red_delete.png} +0 -0
  9. data/app/assets/images/iconza/{red/edit.png → icons/red_edit.png} +0 -0
  10. data/app/assets/images/iconza/icons/red_move.png +0 -0
  11. data/app/assets/javascripts/render_tree_helper.js.coffee +82 -0
  12. data/app/assets/javascripts/sortable_tree/initializer.js.coffee +54 -0
  13. data/app/assets/stylesheets/sortable_tree.css.scss +106 -0
  14. data/app/assets/stylesheets/tree.css.scss +26 -29
  15. data/app/controllers/the_sortable_tree_controller.rb +3 -2
  16. data/app/helpers/render_sortable_tree_helper.rb +62 -0
  17. data/app/helpers/render_tree_helper.rb +45 -0
  18. data/app/helpers/the_sortable_tree_helper.rb +67 -52
  19. data/app/views/sortable/client/_tree.html.erb +9 -0
  20. data/app/views/tree/client/_tree.html.erb +23 -0
  21. data/lib/fake.example +44 -0
  22. data/lib/generators/the_sortable_tree/views_generator.rb +29 -18
  23. data/lib/the_sortable_tree.rb +4 -8
  24. data/lib/the_sortable_tree/engine.rb +1 -1
  25. data/lib/the_sortable_tree/version.rb +1 -1
  26. metadata +31 -60
  27. data/app/assets/images/iconza/blue/add.png +0 -0
  28. data/app/assets/images/iconza/blue/delete.png +0 -0
  29. data/app/assets/images/iconza/blue/down.png +0 -0
  30. data/app/assets/images/iconza/blue/downloads_folder.png +0 -0
  31. data/app/assets/images/iconza/blue/edit.png +0 -0
  32. data/app/assets/images/iconza/blue/move.png +0 -0
  33. data/app/assets/images/iconza/blue/up.png +0 -0
  34. data/app/assets/images/iconza/gray/down.png +0 -0
  35. data/app/assets/images/iconza/gray/lock.png +0 -0
  36. data/app/assets/images/iconza/gray/mail.png +0 -0
  37. data/app/assets/images/iconza/gray/push_pin.png +0 -0
  38. data/app/assets/images/iconza/gray/up.png +0 -0
  39. data/app/assets/images/iconza/red/down.png +0 -0
  40. data/app/assets/images/iconza/red/newspaper.png +0 -0
  41. data/app/assets/images/iconza/red/trash.png +0 -0
  42. data/app/assets/images/iconza/red/up.png +0 -0
  43. data/app/assets/images/iconza/red/zoom.png +0 -0
  44. data/app/assets/javascripts/comments/base.js.coffee +0 -46
  45. data/app/assets/javascripts/sortable/base.js.coffee +0 -47
  46. data/app/assets/stylesheets/comments_tree.css.scss +0 -84
  47. data/app/assets/stylesheets/sortable.css.scss +0 -106
  48. data/app/views/comments/base/_children.html.haml +0 -1
  49. data/app/views/comments/base/_comment.html.haml +0 -8
  50. data/app/views/comments/base/_new_comment_form.html.haml +0 -18
  51. data/app/views/comments/base/_node.html.haml +0 -3
  52. data/app/views/comments/base/_tree.html.haml +0 -5
  53. data/app/views/sortable/base/_children.html.haml +0 -1
  54. data/app/views/sortable/base/_controls.html.haml +0 -16
  55. data/app/views/sortable/base/_link.html.haml +0 -7
  56. data/app/views/sortable/base/_new.html.haml +0 -3
  57. data/app/views/sortable/base/_node.html.haml +0 -3
  58. data/app/views/sortable/base/_tree.html.haml +0 -12
  59. data/app/views/tree/base/_children.html.haml +0 -1
  60. data/app/views/tree/base/_link.html.haml +0 -1
  61. data/app/views/tree/base/_node.html.haml +0 -3
  62. data/app/views/tree/base/_tree.html.haml +0 -3
  63. data/config/locales/en.yml +0 -31
  64. data/config/locales/ru.yml +0 -31
  65. data/lib/tasks/the_sortable_tree.rake +0 -4
@@ -1,13 +1,19 @@
1
1
  module TheSortableTreeHelper
2
2
  # Publicated by MIT
3
3
  # Nested Set View Helper
4
- # Ilya Zykin, zykin-ilya@ya.ru, Russia, Ivanovo 2009-2012
4
+
5
+ # Ilya Zykin, zykin-ilya@ya.ru, Russia [Ivanovo, Saint Petersburg] 2009-2013
5
6
  # github.com/the-teacher
6
- #-------------------------------------------------------------------------------------------------------
7
7
 
8
- # = sortable_tree @pages, :new_url => new_page_url, :max_levels => 5
9
- # = sortable_tree @products, :new_url => new_product_url, :path => 'products/the_sortable_tree'
10
- # = sortable_tree @catalogs, :namespace => :admin, :new_url => new_catalog_url, :max_levels => 5
8
+ # Default renderers
9
+ TREE_RENDERERS = {
10
+ :tree => RenderTreeHelper,
11
+ :sortable => RenderSortableTreeHelper
12
+ }
13
+
14
+ ###############################################
15
+ # Common Base Methods
16
+ ###############################################
11
17
 
12
18
  def define_class_of_elements_of tree
13
19
  case
@@ -17,74 +23,83 @@ module TheSortableTreeHelper
17
23
  end
18
24
  end
19
25
 
20
- # types:
21
- # tree
22
- # sortable
23
- # comments
24
- def sortable_tree(tree, options= {})
25
- opts = {
26
- :max_levels => 3,
27
- :type => :tree,
28
- :js => false,
29
- :path => false,
30
- :title => :title,
31
- :klass => define_class_of_elements_of(tree),
32
- # comments options
33
- :node_id => :id,
34
- :contacts_field => :email,
35
- :content_field => :content,
36
- :raw_content_field => :raw_content
37
- }.merge! options
38
-
39
- # RAILS require
40
- opts[:namespace] = Array.wrap opts[:namespace]
41
-
42
- # PATH building
43
- unless opts[:path]
44
- variant = 'base'
45
- variant = 'js' if opts[:js]
46
- opts[:path] = "#{opts[:type]}/#{variant}"
47
- end
48
-
49
- render :partial => "#{opts[:path]}/tree", :locals => { :tree => sortable_tree_builder(tree, opts), :opts => opts }
26
+ def build_tree_html context, render_module, options = {}
27
+ render_module::Render::render_node(self, options)
50
28
  end
51
29
 
52
- def sortable_tree_builder(tree, options= {})
30
+ ###############################################
31
+ # Server Side Render Tree Helper
32
+ ###############################################
33
+
34
+ def build_server_tree(tree, options= {})
53
35
  result = ''
54
36
  opts = {
55
- :id => :id, # node id field
56
- :node => nil, # node
57
- :root => false, # is it root node?
58
- :level => 0 # recursion level
37
+ # node and base node params
38
+ :id => :id, # node id field
39
+ :title => :title, # name of title fileld
40
+ :node => nil, # node
41
+ # base options
42
+ :type => :tree, # tree type
43
+ :root => false, # is it root node?
44
+ :level => 0, # recursion level
45
+ :namespace => [], # :admin
46
+ # SYSTEM boost array
47
+ :boost => [] # BOOST! array
59
48
  }.merge!(options)
60
49
 
50
+ # Basic vars
61
51
  root = opts[:root]
62
52
  node = opts[:node]
63
53
 
54
+ # namespace prepare [Rails require]
55
+ opts[:namespace] = Array.wrap opts[:namespace]
56
+
57
+ # Module with **Render** class
58
+ opts[:render_module] = TREE_RENDERERS[opts[:type]] unless opts[:render_module]
59
+
60
+ # Define tree class
61
+ opts[:klass] = define_class_of_elements_of(tree) unless opts[:klass]
62
+
63
+ # BOOST PATCH (BUILD ONCE)
64
+ if opts[:boost].empty?
65
+ tree.each do |item|
66
+ num = item.parent_id || 0
67
+ opts[:boost][num] = [] unless opts[:boost][num]
68
+ opts[:boost][num].push item
69
+ end
70
+ end
71
+
64
72
  unless node
65
- roots = tree.select{ |elem| elem.parent_id.nil? }
73
+ # RENDER ROOTS
74
+ roots = opts[:boost][0]
66
75
 
67
- # TODO: try to remove compact
68
- # children rendering
69
- if roots.empty? && !tree.empty?
76
+ # define roots, if it's need
77
+ if roots.nil? && !tree.empty?
70
78
  min_parent_id = tree.map(&:parent_id).compact.min
71
79
  roots = tree.select{ |elem| elem.parent_id == min_parent_id }
72
80
  end
73
81
 
82
+ # children rendering
74
83
  roots.each do |root|
75
- _opts = opts.merge({:node => root, :root => true, :level => opts[:level].next})
76
- result << sortable_tree_builder(tree, _opts)
84
+ _opts = opts.merge({ :node => root, :root => true, :level => opts[:level].next, :boost => opts[:boost] })
85
+ result << build_server_tree(tree, _opts)
77
86
  end
78
87
  else
88
+ # RENDER NODE'S CHILDREN
79
89
  children_res = ''
80
- children = tree.select{|elem| elem.parent_id == node.id}
81
- opts.merge!({:has_children => children.blank?})
82
- children.each do |elem|
83
- _opts = opts.merge({:node => elem, :root => false, :level => opts[:level].next})
84
- children_res << sortable_tree_builder(tree, _opts)
90
+ children = opts[:boost][node.id]
91
+ opts.merge!({ :has_children => children.blank? })
92
+
93
+ unless children.nil?
94
+ children.each do |elem|
95
+ _opts = opts.merge({ :node => elem, :root => false, :level => opts[:level].next, :boost => opts[:boost] })
96
+ children_res << build_server_tree(tree, _opts)
97
+ end
85
98
  end
86
- result << render(:partial => "#{opts[:path]}/node", :locals => {:opts => opts, :root => root, :node => node, :children => children_res})
99
+
100
+ result << build_tree_html(self, opts[:render_module], opts.merge({ :root => root, :node => node, :children => children_res }))
87
101
  end
102
+
88
103
  raw result
89
104
  end
90
105
  end
@@ -0,0 +1,9 @@
1
+ <% unless tree.blank? %>
2
+ <i class='sortable_tree' style='display:none'>
3
+ <i class='data'><%= tree.to_json %></i>
4
+ <i class='locale'><%= t(:sortable).to_json %></i>
5
+ <i class='klass'><%= opts[:klass] %></i>
6
+ <i class='plural'><%= opts[:klass].pluralize %></i>
7
+ <i class='rebuild_url'><%= url_for(:controller => opts[:klass].pluralize, :action => :rebuild) %></i>
8
+ </i>
9
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <h1><%= tree.size %></h1>
2
+
3
+ <div class='tree_block'>
4
+ <ol class='tree'>
5
+ <%= server_build_tree(tree) %>
6
+ </ol>
7
+ </div>
8
+
9
+ <% unless tree.blank? %>
10
+ <i class='render_tree' style='display:none' data-locale="<%= t(:tree).to_json %>" data-klass="<%= opts[:klass] %>" data-plural="<%= opts[:klass].pluralize %>">
11
+ </i>
12
+ <% end %>
13
+
14
+ <% tree.each do |item| %>
15
+
16
+ <li>
17
+ <div class='item'>
18
+ <h4><a href='#'><%= item.title %></a></h4>
19
+ <p><%= item.content %></p>
20
+ </div>
21
+ </li>
22
+
23
+ <% end %>
data/lib/fake.example ADDED
@@ -0,0 +1,44 @@
1
+ book = {
2
+ 'Programs' => {
3
+ 'Lexical Structure' => [
4
+ 'Comments',
5
+ 'Documentation',
6
+ 'Whitespace',
7
+ 'Literals',
8
+ 'Identifiers'
9
+ ]
10
+ }
11
+ }
12
+
13
+ def create_hub user, title
14
+ obj = user.send(:hubs).new
15
+ obj.title = title
16
+ obj.hub_type = :book
17
+ obj.state = :published
18
+ obj.save!
19
+ obj
20
+ end
21
+
22
+ def build_page_tree user, book, parent_obj = nil
23
+ book.each_pair do |key, value|
24
+ obj = create_hub(user, key)
25
+ obj.move_to_child_of(parent_obj) if parent_obj
26
+ parent_obj = obj
27
+
28
+ if value.is_a? Hash
29
+ build_page_tree(user, value, parent_obj)
30
+ end
31
+
32
+ if value.is_a? Array
33
+ value.each do |key|
34
+ obj = create_hub(user, key)
35
+ obj.move_to_child_of(parent_obj)
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+
42
+ build_page_tree(User.first, book)
43
+
44
+ Hub.roots.of_(:book).last.self_and_descendants
@@ -4,31 +4,42 @@ module TheSortableTree
4
4
  source_root File.expand_path('../../../../app/views', __FILE__)
5
5
 
6
6
  def self.banner
7
- <<-BANNER.chomp
8
- rails g the_sortable_tree:views MODEL [tree|sortable|comments]
9
- Copies files for rendering sortable nested set
10
- BANNER
7
+ <<-BANNER.chomp
8
+
9
+ bundle exec rails g the_sortable_tree:views tree
10
+ bundle exec rails g the_sortable_tree:views sortable
11
+ bundle exec rails g the_sortable_tree:views helper
12
+
13
+ bundle exec rails g the_sortable_tree:views assets
14
+
15
+ BANNER
11
16
  end
12
17
 
13
18
  def copy_sortable_tree_files
14
- # sortable
15
- # comments
16
- # tree
17
- if ARGV[1] == 'sortable'
18
- directory "../assets/javascripts/sortable", "app/assets/javascripts/sortable"
19
- directory "sortable/base", "app/views/#{folder}/sortable/base"
20
- elsif ARGV[1] == 'comments'
21
- directory "../assets/javascripts/comments", "app/assets/javascripts/comments"
22
- directory "comments/base", "app/views/#{folder}/comments/base"
23
- else
24
- directory "tree/base", "app/views/#{folder}/tree/base"
25
- end
19
+ copy_helper_files
26
20
  end
27
21
 
28
22
  private
29
23
 
30
- def folder
31
- name.pluralize.downcase
24
+ def param_name
25
+ name.downcase
26
+ end
27
+
28
+ def copy_helper_files
29
+ if param_name == 'tree'
30
+ puts "Copy of tree render helper file"
31
+ copy_file "../helpers/render_tree_helper.rb", "app/helpers/render_tree_helper.rb"
32
+ elsif param_name == 'sortable'
33
+ puts "Copy of sortable tree render helper file"
34
+ copy_file "../helpers/render_sortable_tree_helper.rb", "app/helpers/render_sortable_tree_helper.rb"
35
+ elsif param_name == 'helper'
36
+ puts "Copy of base nested set render helper file"
37
+ copy_file "../helpers/the_sortable_tree_helper.rb", "app/helpers/the_sortable_tree_helper.rb"
38
+ elsif param_name == 'assets'
39
+ directory "../assets/javascripts", "app/assets/javascripts"
40
+ else
41
+ puts "Wrong params - use only [assets | tree | sortable] values"
42
+ end
32
43
  end
33
44
 
34
45
  end
@@ -1,18 +1,14 @@
1
- # So, ERB and SLIM fans want to make gem became independent of HAML
2
- # Ok, let it be. But you will convert view partials youself
3
- # require "haml"
4
-
5
1
  require "the_sortable_tree/engine"
6
2
  require "the_sortable_tree/version"
7
3
 
4
+ # include TheSortableTree::Scopes
8
5
  module TheSortableTree
9
- # include TheSortableTree::Scopes
10
6
  module Scopes
11
7
  def self.included(base)
12
8
  base.class_eval do
13
- scope :nested_set, order('lft ASC')
14
- scope :reversed_nested_set, order('lft DESC')
9
+ scope :nested_set, -> { order('lft ASC') }
10
+ scope :reversed_nested_set, -> { order('lft DESC') }
15
11
  end
16
12
  end
17
13
  end
18
- end
14
+ end
@@ -3,4 +3,4 @@ require 'rails'
3
3
 
4
4
  module TheSortableTree
5
5
  class Engine < Rails::Engine; end
6
- end#TheRole
6
+ end
@@ -1,3 +1,3 @@
1
1
  module TheSortableTree
2
- VERSION = "1.9.4"
2
+ VERSION = "2.0.0"
3
3
  end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: the_sortable_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.4
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
- - Ilya N. Zykin, Matthew Clark, Mikhail Dieterle
8
+ - Ilya N. Zykin, Mikhail Dieterle, Matthew Clark
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-17 00:00:00.000000000Z
12
+ date: 2013-01-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &69384430 !ruby/object:Gem::Requirement
16
+ requirement: &84664520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *69384430
24
+ version_requirements: *84664520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sqlite3
27
- requirement: &69384220 !ruby/object:Gem::Requirement
27
+ requirement: &84664130 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *69384220
35
+ version_requirements: *84664130
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &69374790 !ruby/object:Gem::Requirement
38
+ requirement: &84663700 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *69374790
46
+ version_requirements: *84663700
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec-rails
49
- requirement: &69374570 !ruby/object:Gem::Requirement
49
+ requirement: &84663410 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,9 +54,9 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *69374570
58
- description: Sortable awesom_nested_set, Drag&Drop GUI for awesom_nested_set, View
59
- Helper for nested set, Nested Comments
57
+ version_requirements: *84663410
58
+ description: Drag&Drop GUI for awesom_nested_set. Render Tree Helper. Very fast! Ready
59
+ for Rails 4
60
60
  email:
61
61
  - zykin-ilya@ya.ru
62
62
  executables: []
@@ -65,57 +65,28 @@ extra_rdoc_files:
65
65
  - README.md
66
66
  files:
67
67
  - app/controllers/the_sortable_tree_controller.rb
68
- - app/assets/images/iconza/red/edit.png
69
- - app/assets/images/iconza/red/down.png
70
- - app/assets/images/iconza/red/zoom.png
71
- - app/assets/images/iconza/red/trash.png
72
- - app/assets/images/iconza/red/newspaper.png
73
- - app/assets/images/iconza/red/delete.png
74
- - app/assets/images/iconza/red/up.png
75
- - app/assets/images/iconza/red/add.png
76
- - app/assets/images/iconza/gray/mail.png
77
- - app/assets/images/iconza/gray/edit.png
78
- - app/assets/images/iconza/gray/down.png
79
- - app/assets/images/iconza/gray/delete.png
80
- - app/assets/images/iconza/gray/push_pin.png
81
- - app/assets/images/iconza/gray/up.png
82
- - app/assets/images/iconza/gray/add.png
83
- - app/assets/images/iconza/gray/lock.png
84
- - app/assets/images/iconza/blue/edit.png
85
- - app/assets/images/iconza/blue/down.png
86
- - app/assets/images/iconza/blue/downloads_folder.png
87
- - app/assets/images/iconza/blue/move.png
88
- - app/assets/images/iconza/blue/delete.png
89
- - app/assets/images/iconza/blue/up.png
90
- - app/assets/images/iconza/blue/add.png
68
+ - app/assets/images/iconza/icons/edit.png
69
+ - app/assets/images/iconza/icons/red_edit.png
70
+ - app/assets/images/iconza/icons/red_delete.png
71
+ - app/assets/images/iconza/icons/red_move.png
72
+ - app/assets/images/iconza/icons/red_add.png
73
+ - app/assets/images/iconza/icons/move.png
74
+ - app/assets/images/iconza/icons/delete.png
75
+ - app/assets/images/iconza/icons/add.png
91
76
  - app/assets/stylesheets/tree.css.scss
92
- - app/assets/stylesheets/comments_tree.css.scss
93
- - app/assets/stylesheets/sortable.css.scss
94
- - app/assets/javascripts/comments/base.js.coffee
95
- - app/assets/javascripts/sortable/base.js.coffee
77
+ - app/assets/stylesheets/sortable_tree.css.scss
96
78
  - app/assets/javascripts/jquery.ui.nestedSortable.js
97
- - app/views/comments/base/_children.html.haml
98
- - app/views/comments/base/_node.html.haml
99
- - app/views/comments/base/_tree.html.haml
100
- - app/views/comments/base/_comment.html.haml
101
- - app/views/comments/base/_new_comment_form.html.haml
102
- - app/views/sortable/base/_children.html.haml
103
- - app/views/sortable/base/_node.html.haml
104
- - app/views/sortable/base/_link.html.haml
105
- - app/views/sortable/base/_tree.html.haml
106
- - app/views/sortable/base/_new.html.haml
107
- - app/views/sortable/base/_controls.html.haml
108
- - app/views/tree/base/_children.html.haml
109
- - app/views/tree/base/_node.html.haml
110
- - app/views/tree/base/_link.html.haml
111
- - app/views/tree/base/_tree.html.haml
79
+ - app/assets/javascripts/render_tree_helper.js.coffee
80
+ - app/assets/javascripts/sortable_tree/initializer.js.coffee
81
+ - app/views/sortable/client/_tree.html.erb
82
+ - app/views/tree/client/_tree.html.erb
83
+ - app/helpers/render_tree_helper.rb
112
84
  - app/helpers/the_sortable_tree_helper.rb
113
- - config/locales/ru.yml
114
- - config/locales/en.yml
85
+ - app/helpers/render_sortable_tree_helper.rb
115
86
  - lib/the_sortable_tree/version.rb
116
87
  - lib/the_sortable_tree/engine.rb
117
- - lib/tasks/the_sortable_tree.rake
118
88
  - lib/generators/the_sortable_tree/views_generator.rb
89
+ - lib/fake.example
119
90
  - lib/the_sortable_tree.rb
120
91
  - MIT-LICENSE
121
92
  - Rakefile
@@ -175,8 +146,8 @@ rubyforge_project: the_sortable_tree
175
146
  rubygems_version: 1.8.15
176
147
  signing_key:
177
148
  specification_version: 3
178
- summary: Sortable awesom_nested_set, Drag&Drop GUI for awesom_nested_set, View Helper
179
- for nested set, Nested Comments
149
+ summary: Drag&Drop GUI for awesom_nested_set. Render Tree Helper. Very fast! Ready
150
+ for Rails 4
180
151
  test_files:
181
152
  - spec/controlllers/controller_mixin_spec.rb
182
153
  - spec/spec_helper.rb