mustache_render 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,17 +9,43 @@ MustacheRender.configure do |config|
9
9
  config.file_template_root_path = "#{Rails.root}/app/templates"
10
10
 
11
11
  # 默认的文件模板的扩展名称
12
- config.file_template_extension = 'mustache'
12
+ config.file_template_extension = '.mustache'
13
13
 
14
- # 当模板缺少的时候是否抛出异常
14
+ # 默认的数据模板的扩展名称
15
+ config.db_template_extension = '.mustache'
16
+
17
+ # 当字段缺少的时候是否抛出异常
15
18
  config.raise_on_context_miss = false
16
19
 
20
+ # 当数据库模板不存在时候是否抛出异常
21
+ config.raise_on_db_template_miss = true
22
+
23
+ # 当文件模板不存在时候是否抛出异常
24
+ config.raise_on_file_template_miss = true
25
+
26
+ ### 模板的相关配置 ###########################
27
+ # 数据库模板是否需要缓存
28
+ config.db_template_cache = true
29
+ # 文件模板是否需要缓存
30
+ config.file_template_cache = false
31
+ # 数据库模板缓存过期时间
32
+ config.db_template_cache_expires_in = 1.hours
33
+ # 文件模板缓存的过期时间, 注意文件系统没有自动清理缓存的机制,建议设置的短一些
34
+ config.file_template_cache_expires_in = 1.minutes
35
+ # 缓存的媒介
36
+ config.cache_store = Rails.cache
37
+
38
+ # 版本适配器的配置
17
39
  config.adapter_configure do |adapter|
18
40
 
19
41
  end
20
42
 
43
+ # 管理中心是否需要登录
21
44
  config.manage_center_need_login = true
45
+ # 用户登录的url
22
46
  config.user_login_url = '/login'
47
+ # 管理员登录失败后跳往的URL
23
48
  config.manager_authenticate_fail_url = '/login'
49
+
24
50
  end
25
51
 
@@ -25,7 +25,7 @@ module MustacheRender
25
25
  # 默认的渲染媒介
26
26
  #
27
27
  def default_render_media
28
- @default_render_media ||= :db
28
+ @default_render_media ||= :file
29
29
  end
30
30
 
31
31
  def default_render_media= media
@@ -48,6 +48,69 @@ module MustacheRender
48
48
  @user_login_url ||= url
49
49
  end
50
50
 
51
+ def cache
52
+ return @_cache_store if defined?(@_cache_store)
53
+
54
+ @_cache_store ||= Rails.cache
55
+ # @_cache_store ||= MemCache.new('localhost:11211', :namespace => 'mustache_render#cache')
56
+ end
57
+
58
+ def cache_store= cache_store
59
+ @_cache_store ||= cache_store
60
+ end
61
+
62
+ #
63
+ # 是否开启缓存
64
+ #
65
+ def db_template_cache?
66
+ if defined?(@_db_template_cache)
67
+ @_db_template_cache
68
+ else
69
+ true
70
+ end
71
+ end
72
+
73
+ #
74
+ # 是否开启缓存
75
+ #
76
+ def file_template_cache?
77
+ if defined?(@_file_template_cache)
78
+ @_file_template_cache
79
+ else
80
+ false
81
+ end
82
+ end
83
+
84
+ #
85
+ # 设置是否启用缓存
86
+ #
87
+ def db_template_cache= user_cache
88
+ @_db_template_cache = user_cache unless defined?(@_db_template_cache)
89
+ end
90
+
91
+ #
92
+ # 设置是否启用缓存
93
+ #
94
+ def file_template_cache= user_cache
95
+ @_file_template_cache = user_cache unless defined?(@_file_template_cache)
96
+ end
97
+
98
+ def db_template_cache_expires_in
99
+ @db_template_cache_expires_in ||= 1.hours
100
+ end
101
+
102
+ def file_template_cache_expires_in
103
+ @file_template_cache_expires_in ||= 5.minutes
104
+ end
105
+
106
+ def db_template_cache_expires_in= expires_in
107
+ @db_template_cache_expires_in ||= expires_in
108
+ end
109
+
110
+ def file_template_cache_expires_in= expires_in
111
+ @file_template_cache_expires_in ||= expires_in
112
+ end
113
+
51
114
  def manage_center_need_login?
52
115
  if defined?(@manage_center_need_login)
53
116
  @manage_center_need_login
@@ -76,20 +139,46 @@ module MustacheRender
76
139
  @file_template_root_path ||= path
77
140
  end
78
141
 
142
+ def db_template_extension
143
+ @db_template_extension ||= '.mustache'
144
+ end
145
+
146
+ def db_template_extension= name
147
+ @db_template_extension ||= name
148
+ end
149
+
79
150
  def file_template_extension
80
- @file_template_extension ||= 'mustache'
151
+ @file_template_extension ||= '.mustache'
81
152
  end
82
153
 
83
154
  def file_template_extension= name
84
155
  @file_template_extension ||= name
85
156
  end
86
157
 
158
+ # 是否抛出文件模板丢失的异常?
159
+ def raise_on_file_template_miss= _bool
160
+ @raise_on_file_template_miss = _bool unless defined?(@raise_on_file_template_miss)
161
+ end
162
+
163
+ def raise_on_file_template_miss?
164
+ defined?(@raise_on_file_template_miss) ? @raise_on_file_template_miss : true
165
+ end
166
+
167
+ # 是否抛出数据库模板miss的异常
168
+ def raise_on_db_template_miss= _bool
169
+ @raise_on_db_template_miss = _bool unless defined?(@raise_on_db_template_miss)
170
+ end
171
+
172
+ def raise_on_db_template_miss?
173
+ defined?(@raise_on_db_template_miss) ? @raise_on_db_template_miss : true
174
+ end
175
+
87
176
  def raise_on_context_miss?
88
177
  defined?(@raise_on_context_miss) ? @raise_on_context_miss : false
89
178
  end
90
179
 
91
- def raise_on_context_miss=(boolean)
92
- @raise_on_context_miss = boolean
180
+ def raise_on_context_miss=(_bool)
181
+ @raise_on_context_miss = _bool unless defined?(@raise_on_context_miss)
93
182
  end
94
183
 
95
184
  def manage_view_base
@@ -20,11 +20,16 @@ module MustacheRender::Models
20
20
  validates_presence_of :folder_id
21
21
  validates_presence_of :name
22
22
  validates_presence_of :change_log, :if => Proc.new { |r| !(r.new_record?) }
23
+ validates_uniqueness_of :name, :scope => [:folder_id, :name]
23
24
 
24
25
  validate do |r|
25
26
  r.errors.add :change, '没有改动' if !(r.new_record?) && !(r.changed?)
26
27
  end
27
28
 
29
+ before_save do |r|
30
+ ::MustacheRender::Mustache.delete_partial_cache(r.full_path_was, :db)
31
+ end
32
+
28
33
  extend ClassMethods
29
34
  include InstanceMethods
30
35
  end
@@ -38,12 +43,27 @@ module MustacheRender::Models
38
43
  # 首先获取文件夹的名称, 然后获取文件名
39
44
  tmp_paths = name.to_s.split('/')
40
45
 
41
- template_name = tmp_paths.pop.to_s
46
+ template_name = ::MustacheRender::Mustache.generate_template_name(
47
+ tmp_paths.pop.to_s,
48
+ ::MustacheRender.config.db_template_extension
49
+ )
42
50
 
43
51
  folder_full_path = "#{tmp_paths.join('/')}"
52
+
53
+ # 需要以 / 开头,此处fix一下这里
54
+ unless folder_full_path.start_with?('/')
55
+ folder_full_path = "/#{folder_full_path}"
56
+ end
57
+
44
58
  folder = ::MustacheRenderFolder.find_by_full_path(folder_full_path)
45
59
 
46
- self.find_by_folder_id_and_name(folder.try(:id), template_name)
60
+ template = self.find_by_folder_id_and_name(folder.try(:id), template_name)
61
+
62
+ if ::MustacheRender.config.raise_on_db_template_miss? && template.nil?
63
+ raise ::MustacheRender::Mustache::TemplateMiss.new("read db template error: folder_full_path -> #{folder_full_path} template_name: #{template_name}")
64
+ end
65
+
66
+ template
47
67
  end
48
68
  end
49
69
 
@@ -19,18 +19,23 @@ module MustacheRender
19
19
  end
20
20
 
21
21
  def render(data = template, ctx = {})
22
- tpl = templateify(data)
23
-
24
- return tpl.render(context) if ctx == {}
22
+ self.template = data
23
+
24
+ return self.template.render(context) if ctx == {}
25
25
 
26
26
  begin
27
27
  context.push(ctx)
28
- tpl.render(context)
28
+ self.template.render(context)
29
29
  ensure
30
30
  context.pop
31
31
  end
32
32
  end
33
33
 
34
+ # 片段树
35
+ def partials_tree
36
+
37
+ end
38
+
34
39
  # Context accessors.
35
40
  #
36
41
  # view = Mustache.new
@@ -74,13 +79,68 @@ module MustacheRender
74
79
  render(partial(full_path), context)
75
80
  end
76
81
 
77
- def read_template_from_meida name
82
+ def impl_read_db_template name
83
+ db_template = ::MustacheRenderTemplate.find_with_full_path(name)
84
+ db_template.try :content
85
+ end
86
+
87
+ def self.generate_template_name(name, template_extension)
88
+ # 如果路径中以扩展名结尾,则直接去取这个文件
89
+ name = name.to_s.strip
90
+
91
+ if name.start_with?('/')
92
+ name = name[1..-1]
93
+ end
94
+
95
+ if name.end_with?(template_extension)
96
+ "#{name}"
97
+ else
98
+ "#{name}#{template_extension}"
99
+ end
100
+ end
101
+
102
+ def impl_read_file_template name
103
+ # TODO: 对路径的语法需要加强
104
+ full_path = "#{config.file_template_root_path}/#{self.class.generate_template_name(name, config.file_template_extension)}"
105
+ begin
106
+ File.read full_path
107
+ rescue
108
+ if config.raise_on_file_template_miss?
109
+ raise ::MustacheRender::Mustache::TemplateMiss.new("read file template error: #{full_path}")
110
+ else
111
+ ''
112
+ end
113
+ end
114
+ end
115
+
116
+ def read_template_from_media name, media
117
+ # puts "read_template_from_media: #{name} #{media}"
78
118
  case media
79
119
  when :db
80
- db_template = ::MustacheRenderTemplate.find_with_full_path(name)
81
- db_template.try :content
120
+ if ::MustacheRender.config.db_template_cache?
121
+ self.class.fetch_partial_cache name, media, :expires_in => ::MustacheRender.config.db_template_cache_expires_in do
122
+ impl_read_db_template name
123
+ end
124
+ else
125
+ impl_read_db_template name
126
+ end
82
127
  when :file
83
- File.read "#{config.file_template_root_path}/#{name}.#{config.file_template_extension}"
128
+ if ::MustacheRender.config.file_template_cache?
129
+ self.class.fetch_partial_cache name, media, :expires_in => ::MustacheRender.config.file_template_cache_expires_in do
130
+ impl_read_file_template name
131
+ end
132
+ else
133
+ impl_read_file_template name
134
+ end
135
+ end
136
+ end
137
+
138
+ def self.fix_path_name name
139
+ # 需要以 / 开头,此处fix一下这里
140
+ if name.to_s.start_with?('/')
141
+ name.to_s
142
+ else
143
+ "/#{name}"
84
144
  end
85
145
  end
86
146
 
@@ -88,7 +148,39 @@ module MustacheRender
88
148
  # reading templates from a database. It will be rendered by the
89
149
  # context, so all you need to do is return a string.
90
150
  def partial(name)
91
- self.read_template_from_meida name
151
+ name = self.class.fix_path_name name
152
+ # return self.read_template_from_media name, media
153
+ @_cached_partials ||= {}
154
+ (@_cached_partials[media] ||= {})[name] ||= self.read_template_from_media name, media
155
+ end
156
+
157
+ def self.partial_cache_key(name, media)
158
+ raise 'options key: :media must in(:file, :db)' unless [:file, :db].include?(media)
159
+ "MustacheRender::Mustache#Template.cache##{media}##{name}"
160
+ end
161
+
162
+ def self.exist_partial_cache?(name, media)
163
+ ::MustacheRender.config.cache.exist?(self.partial_cache_key(name, media))
164
+ end
165
+
166
+ def self.delete_partial_cache(name, media)
167
+ ::MustacheRender.config.cache.delete(self.partial_cache_key(name, media))
168
+ end
169
+
170
+ def self.fetch_partial_cache(name, media, options={}, &block)
171
+ ::MustacheRender.config.cache.fetch(self.partial_cache_key(name, media), options) do
172
+ if block_given?
173
+ block.call
174
+ end
175
+ end
176
+ end
177
+
178
+ def self.read_partial_cache(name, media)
179
+ ::MustacheRender.config.cache.read(self.partial_cache_key(name, media))
180
+ end
181
+
182
+ def self.write_partial_cache(name, media, value, options={})
183
+ ::MustacheRender.config.cache.write(self.partial_cache_key(name, media), value, options)
92
184
  end
93
185
 
94
186
  # Override this to provide custom escaping.
@@ -165,6 +257,16 @@ module MustacheRender
165
257
  (@template && @template.is_a?(Template)) || self.class.compiled?
166
258
  end
167
259
 
260
+ def template
261
+ return @template if @template
262
+
263
+ self.template = ''
264
+ end
265
+
266
+ def template= template
267
+ @template = templateify(template)
268
+ end
269
+
168
270
  # template_partial => TemplatePartial
169
271
  # template/partial => Template::Partial
170
272
  def self.classify(underscored)
@@ -39,7 +39,7 @@ module MustacheRender
39
39
  # Find the first Mustache in the stack. If we're being rendered
40
40
  # inside a Mustache object as a context, we'll use that one.
41
41
  def mustache_in_stack
42
- @stack.detect { |frame| frame.is_a?(Mustache) }
42
+ @stack.detect { |frame| frame.is_a?(::MustacheRender::Mustache) }
43
43
  end
44
44
 
45
45
  # Allows customization of how Mustache escapes things.
@@ -104,7 +104,7 @@ module MustacheRender
104
104
  end
105
105
  end
106
106
 
107
- if default == :__raise || MustacheRender.config.raise_on_context_miss?
107
+ if default == :__raise || ::MustacheRender.config.raise_on_context_miss?
108
108
  raise ContextMiss.new("Can't find #{name} in #{@stack.inspect}")
109
109
  else
110
110
  default
@@ -102,6 +102,10 @@ module MustacheRender
102
102
  error "Unclosed section #{type.inspect}", pos
103
103
  end
104
104
 
105
+ # puts ""
106
+ # puts "-----------------------------------------------------"
107
+ # puts @result
108
+
105
109
  @result
106
110
  end
107
111
 
@@ -6,6 +6,11 @@ require 'mustache_render/mustache/generator'
6
6
 
7
7
  module MustacheRender
8
8
  class Mustache
9
+ # 模板缺失
10
+ class TemplateMiss < ::RuntimeError
11
+
12
+ end
13
+
9
14
  # A Template represents a Mustache template. It compiles and caches
10
15
  # a raw string template into something usable.
11
16
  #
@@ -15,7 +20,7 @@ module MustacheRender
15
20
  #
16
21
  # You shouldn't use this class directly, instead:
17
22
  #
18
- # >> Mustache.render(template, hash)
23
+ # >> ::MustacheRender::Mustache.render(template, hash)
19
24
  class Template
20
25
  attr_reader :source
21
26
 
@@ -3,7 +3,7 @@ module MustacheRender
3
3
  VERSION_NUMBERS = [
4
4
  VERSION_MAJOR = 0,
5
5
  VERSION_MINOR = 0,
6
- VERSION_BUILD = 7,
6
+ VERSION_BUILD = 9,
7
7
  ]
8
8
 
9
9
  VERSION = VERSION_NUMBERS.join(".")
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'MustacheRender::Mustache.db_render' do
4
+ before :each do
5
+ MustacheRender.configure do |config|
6
+ config.file_template_root_path = ROOT_PATH + '/resources/templates'
7
+ end
8
+ end
9
+
10
+ it 'template scan_tags test' do
11
+ result = MustacheRender::Mustache.file_render 'scan_tags/1', {}
12
+
13
+ end
14
+
15
+ it 'template file 5.mustache render ok' do
16
+ result = MustacheRender::Mustache.file_render 'basic/5', {}
17
+ result.should == <<-TEXT
18
+ file:5, in-file6
19
+
20
+ file:5-2, in-file6
21
+
22
+ file:5-3, in-file6
23
+
24
+ file:5-4, in-file6
25
+
26
+ file:5-5, in-file6
27
+
28
+ file:5-6, in-file6
29
+
30
+ file:5-7, in-file6
31
+
32
+ file:5-8, in-file6
33
+
34
+ file:5-9, in-file6
35
+
36
+ file:5-10, in-file6
37
+
38
+ file:5-11, in-file6
39
+
40
+ TEXT
41
+ end
42
+
43
+ it 'template file 1.mustache render ok' do
44
+ result = MustacheRender::Mustache.file_render 'basic/1', {:filename => '1.mustache'}
45
+ result.should == <<-TEXT
46
+ Hello!1.mustache
47
+ TEXT
48
+ end
49
+
50
+ it 'template 2 with partial 1 render OK' do
51
+ result = MustacheRender::Mustache.file_render 'basic/2', {:filename => 'in1'}
52
+ result.should == <<-TEXT
53
+ file-2Hello!in1
54
+
55
+ TEXT
56
+ end
57
+
58
+ it 'template file 3.mustache partial with 2 render OK' do
59
+ result = MustacheRender::Mustache.file_render 'basic/3', {:filename => 'in1'}
60
+ result.should == <<-TEXT
61
+ file3file-2Hello!in1
62
+
63
+
64
+ TEXT
65
+
66
+ end
67
+ end
@@ -0,0 +1 @@
1
+ Hello!{{filename}}
@@ -0,0 +1 @@
1
+ file-2{{>basic/1}}
@@ -0,0 +1 @@
1
+ file3{{>basic/2}}
@@ -0,0 +1 @@
1
+ file4{{>basic/3}}
@@ -0,0 +1,11 @@
1
+ file:5, {{>basic/6}}
2
+ file:5-2, {{>basic/6}}
3
+ file:5-3, {{>basic/6}}
4
+ file:5-4, {{>basic/6}}
5
+ file:5-5, {{>basic/6}}
6
+ file:5-6, {{>basic/6}}
7
+ file:5-7, {{>basic/6}}
8
+ file:5-8, {{>basic/6}}
9
+ file:5-9, {{>basic/7}}
10
+ file:5-10, {{>basic/7}}
11
+ file:5-11, {{>basic/7}}
@@ -0,0 +1 @@
1
+ {{>/basic/6}}
@@ -0,0 +1,2 @@
1
+ {{>/scan_tags/2}}
2
+ {{>/scan_tags/3}}
@@ -0,0 +1 @@
1
+ {{>/scan_tags/3}}
@@ -0,0 +1,3 @@
1
+ require 'mustache_render'
2
+
3
+ ROOT_PATH = File.dirname(__FILE__) + '/lib'
metadata CHANGED
@@ -1,61 +1,55 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mustache_render
3
- version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 7
10
- version: 0.0.7
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.9
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - happy
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-01-13 00:00:00 +08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2013-01-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: awesome_nested_set
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: sqlite3
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
39
25
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sqlite3
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
47
38
  type: :development
48
- version_requirements: *id002
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
49
46
  description: Description of MustacheRender.
50
- email:
47
+ email:
51
48
  - andywang7259@gmail.com
52
49
  executables: []
53
-
54
50
  extensions: []
55
-
56
51
  extra_rdoc_files: []
57
-
58
- files:
52
+ files:
59
53
  - lib/mustache_render.rb
60
54
  - lib/tasks/mustache_render_tasks.rake
61
55
  - lib/generators/mustache_render/install_generator.rb
@@ -110,42 +104,43 @@ files:
110
104
  - lib/mustache_render/views/mustache_render/manage/folders/_new_2.html.erb
111
105
  - lib/mustache_render/views/mustache_render/manage/folders/_edit_2.html.erb
112
106
  - lib/mustache_render/adapter.rb
107
+ - spec/lib/mustache/file_render_spec.rb
108
+ - spec/lib/resources/templates/basic/6.mustache
109
+ - spec/lib/resources/templates/basic/2.mustache
110
+ - spec/lib/resources/templates/basic/1.mustache
111
+ - spec/lib/resources/templates/basic/7.mustache
112
+ - spec/lib/resources/templates/basic/3.mustache
113
+ - spec/lib/resources/templates/basic/5.mustache
114
+ - spec/lib/resources/templates/basic/4.mustache
115
+ - spec/lib/resources/templates/scan_tags/2.mustache
116
+ - spec/lib/resources/templates/scan_tags/1.mustache
117
+ - spec/lib/resources/templates/scan_tags/3.mustache
118
+ - spec/spec_helper.rb
113
119
  - MIT-LICENSE
114
120
  - Rakefile
115
121
  - README.rdoc
116
- has_rdoc: true
117
122
  homepage: http://blogsoso.net/
118
123
  licenses: []
119
-
120
124
  post_install_message:
121
125
  rdoc_options: []
122
-
123
- require_paths:
126
+ require_paths:
124
127
  - lib
125
- required_ruby_version: !ruby/object:Gem::Requirement
128
+ required_ruby_version: !ruby/object:Gem::Requirement
126
129
  none: false
127
- requirements:
128
- - - ">="
129
- - !ruby/object:Gem::Version
130
- hash: 3
131
- segments:
132
- - 0
133
- version: "0"
134
- required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  none: false
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- hash: 3
140
- segments:
141
- - 0
142
- version: "0"
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
143
140
  requirements: []
144
-
145
141
  rubyforge_project:
146
- rubygems_version: 1.3.7
142
+ rubygems_version: 1.8.24
147
143
  signing_key:
148
144
  specification_version: 3
149
145
  summary: Summary of MustacheRender.
150
146
  test_files: []
151
-