qml 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 525fa2715a8aadc120216147318e0179a578d546
4
- data.tar.gz: ca001300069503c335494e26bd443ef123b56179
3
+ metadata.gz: 281f3641f4c5a3441c260dd874168fe99e6ce991
4
+ data.tar.gz: 46b5c43d00a8a73d1553b327910581fe4569d147
5
5
  SHA512:
6
- metadata.gz: e6468fcf25055c17367415cca0d62b540eacf732de0028958a1337af8e9b157c85a9602e4fc07b47b9a64f130a8797e76dfdf6bcd43b2f9907c41cbfb354f627
7
- data.tar.gz: 865173142d1e3e4ed48d52c08fc52cb77e0fa51b43188388b3fe9074d9b273e1fc9dfdf5f27667505c1b618447038be10f61c1377c82ff007c0010c039e0a291
6
+ metadata.gz: 77c9acdfec3b5689b21425bcdfe4a5a11c2b27e615388faf520dc5c134cde441cfa1700b14f231d59a1a56d3dcc84f8c809b5400d1a4dbc6d5ffc3e8a52ab22b
7
+ data.tar.gz: 83496cea61eb036a083457ee84d7be63b7b7b46d4c8968384eff708ad062b2cc1c5171716bec20c4ec9378a6e93f0d450491bd26835fe9e40ab0d04db94c0663
data/README.md CHANGED
@@ -1,25 +1,23 @@
1
- ruby-qml
1
+ ruby-qml [![Gem Version](https://badge.fury.io/rb/qml.svg)](http://badge.fury.io/rb/qml)
2
2
  ================
3
3
 
4
- [![Gem Version](https://badge.fury.io/rb/qml.svg)](http://badge.fury.io/rb/qml)
4
+ ruby-qml is a QML / Qt Quick wrapper for Ruby.
5
+ It provides bindings between QML and Ruby and enables you to use Qt Quick-based GUI from Ruby.
6
+
7
+ * [Documentation](http://rubydoc.info/github/seanchas116/ruby-qml/master/frames)
8
+ * [Examples](https://github.com/seanchas116/ruby-qml/tree/master/examples)
9
+ * [Changelog](https://github.com/seanchas116/ruby-qml/blob/master/changes.md)
10
+
5
11
  [![Dependency Status](https://gemnasium.com/seanchas116/ruby-qml.svg)](https://gemnasium.com/seanchas116/ruby-qml)
6
12
  [![Build Status](https://travis-ci.org/seanchas116/ruby-qml.svg?branch=master)](https://travis-ci.org/seanchas116/ruby-qml)
7
13
  [![Coverage Status](https://coveralls.io/repos/seanchas116/ruby-qml/badge.png?branch=master)](https://coveralls.io/r/seanchas116/ruby-qml?branch=master)
8
14
  [![Inline docs](http://inch-ci.org/github/seanchas116/ruby-qml.png?branch=master)](http://inch-ci.org/github/seanchas116/ruby-qml)
9
15
 
10
- ruby-qml is a QML / Qt Quick wrapper for Ruby.
11
- It provides bindings between QML and Ruby and enables you to use Qt Quick-based GUI from Ruby.
12
-
13
16
  ## What you can do with ruby-qml
14
17
 
15
18
  * Develop desktop GUI applications only with Ruby and QML
16
19
  * Easily combine codes written in C++ and Qt with your Ruby code
17
20
 
18
- ## Documentation and Examples
19
-
20
- * [Documentation](http://rubydoc.info/github/seanchas116/ruby-qml/master/frames)
21
- * [Examples](https://github.com/seanchas116/ruby-qml/tree/master/examples)
22
-
23
21
  ## Gallery
24
22
 
25
23
  [![Screenshot](https://raw.github.com/seanchas116/ruby-qml/master/examples/todo_sequel/capture.png)](https://github.com/seanchas116/ruby-qml/tree/master/examples/todo_sequel)
@@ -28,29 +26,41 @@ It provides bindings between QML and Ruby and enables you to use Qt Quick-based
28
26
 
29
27
  ## Installation
30
28
 
31
- ruby-qml requires **Ruby 1.9 or later**.
29
+ ### Requirements
30
+
31
+ * **Ruby 1.9 or later**
32
+ * **OS X or Linux**
33
+ * pkg-config
34
+ * libffi
35
+ * Qt 5.2 or later
32
36
 
33
37
  ### OS X with Homebrew
34
38
 
35
- Run the following commands to install ruby-qml on OS X with Homebrew:
39
+ To install ruby-qml on OS X with Homebrew, run the following commands:
36
40
 
37
- $ brew install pkg-config
38
- $ brew install libffi
39
- $ brew install qt5
41
+ $ brew install pkg-config libffi qt5
40
42
  $ gem install qml -- --with-libffi-dir=$(brew --prefix libffi) --with-qt-dir=$(brew --prefix qt5)
41
43
 
42
- ### General (OSX and Linux)
44
+ Both libffi and Qt5 are keg-only in Homebrew, so you must specify their paths explicitly (or force linking).
43
45
 
44
- #### Requirements
46
+ If you use [official Qt installation](http://qt-project.org/downloads), for example:
45
47
 
46
- * pkg-config
47
- * libffi
48
- * Qt 5.2 or later
48
+ $ brew install pkg-config libffi
49
+ $ gem install qml -- --with-libffi-dir=$(brew --prefix libffi) --with-qt-dir=~/Qt/5.3/clang_64
49
50
 
50
- To install, use this command after installing requirements:
51
+ The Qt installation path (`~/Qt/5.3/clang_64` in this example) depends on your Qt installation configuration and Qt version.
52
+
53
+ ### General (OSX and Linux)
51
54
 
52
55
  $ gem install qml
53
56
 
57
+ #### Options
58
+
59
+ * `--with-libffi-dir=[dir]`
60
+ * libffi installation directory (optional).
61
+ * `--with-qt-dir=[dir]`
62
+ * Qt installation directory (optional).
63
+
54
64
  ### Use Gemfile
55
65
 
56
66
  Add this line to your Gemfile:
@@ -75,6 +85,8 @@ The configuration will be saved in `~/.bundle/config`.
75
85
  The following code loads a QML file and shows an application window titled "Hello, world!".
76
86
 
77
87
  ```ruby
88
+ require 'qml'
89
+
78
90
  QML.application do |app|
79
91
  app.load_path Pathname(__FILE__) + '../main.qml'
80
92
  end
@@ -158,7 +170,6 @@ ApplicationWindow {
158
170
  id: textField
159
171
  }
160
172
  Text {
161
- y: 100
162
173
  id: text
163
174
  text: fizzBuzz.result
164
175
  }
@@ -373,9 +384,14 @@ class MyPlugin : public QObject
373
384
  {
374
385
  Q_OBJECT
375
386
  Q_PLUGIN_METADATA(IID "org.myplugin.MyPlugin")
387
+ signals:
388
+ void added(int value);
389
+
376
390
  public slots:
377
- void foo() {
378
- qDebug() << "foo";
391
+ int add(int x, int y) {
392
+ int result = x + y;
393
+ emit added(result);
394
+ return result;
379
395
  }
380
396
  };
381
397
  ```
@@ -383,7 +399,12 @@ public slots:
383
399
  ```ruby
384
400
  # Ruby
385
401
  plugin = QML::PluginLoader.new(directory, "myplugin").instance
386
- plugin.foo
402
+
403
+ plugin.added.connect do |value|
404
+ puts "added value: #{value}"
405
+ end
406
+
407
+ plugin.add(1, 2) #=> 3
387
408
  ```
388
409
 
389
410
  ### Garbage collection
data/changes.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.0.5 (2014-07-31)
2
+
3
+ * Support official Qt installation on Mac
4
+
1
5
  ## 0.0.4 (2014-07-24)
2
6
 
3
7
  * Fix 100% CPU usage in idling
@@ -18,7 +18,6 @@ ApplicationWindow {
18
18
  id: textField
19
19
  }
20
20
  Text {
21
- y: 100
22
21
  id: text
23
22
  text: fizzBuzz.result
24
23
  }
data/ext/qml/extconf.rb CHANGED
@@ -39,7 +39,9 @@ class Configurator
39
39
  qmake_opts = @debug_enabled ? 'CONFIG+=debug' : ''
40
40
  Pathname(__FILE__).+("../plugins").children.select(&:directory?).each do |dir|
41
41
  Dir.chdir(dir) do
42
- system("#{@qmake} #{qmake_opts}") && system('make clean') && system('make') or abort "failed to build plugin: #{dir.basename}"
42
+ system("#{@qmake} #{qmake_opts}") or abort "failed to configurate plugin: #{dir.basename}"
43
+ system('make clean') if enable_config('clean-plugin', false)
44
+ system('make') or abort "failed to build plugin: #{dir.basename}"
43
45
  end
44
46
  end
45
47
  end
@@ -49,15 +51,33 @@ class Configurator
49
51
 
50
52
  PKGS.each do |mod|
51
53
  @cppflags << `#{@pkgconfig} --cflags #{mod}`.chomp
52
- @ldflags << `#{@pkgconfig} --libs #{mod}`.chomp
54
+
55
+ libs =`#{@pkgconfig} --libs #{mod}`.chomp
56
+ @ldflags << libs
57
+
58
+ # add framework search path to cppflags
59
+ libs.split.each do |lib|
60
+ @cppflags << lib if /^-F/ =~ lib
61
+ end
53
62
  end
54
63
 
64
+ # add private header directory of QtCore
55
65
  qtversion = `#{@pkgconfig} --modversion Qt5Core`.chomp
56
66
  `#{@pkgconfig} --cflags-only-I Qt5Core`.split.map { |i| Pathname(i.gsub("-I", "")) }.each do |dir|
57
67
  private_dir = dir + "#{qtversion}/QtCore"
58
68
  @cppflags << "-I#{private_dir}" if private_dir.exist?
59
69
  end
60
70
 
71
+ # include framework headers in Mac
72
+ # (Qt official installer for Mac does not install header files in /include directory)
73
+ if /darwin/ =~ RUBY_PLATFORM
74
+ PKGS.map { |pkg| pkg.gsub(/^Qt5/, 'Qt') }.each do |framework|
75
+ @cppflags << "-I#{@qt_path + "lib/#{framework}.framework/Headers"}"
76
+ end
77
+ # add private header directory of QtCore
78
+ @cppflags << "-I#{@qt_path}/lib/QtCore.framework/Headers/#{qtversion}/QtCore"
79
+ end
80
+
61
81
  $CPPFLAGS += " #{@cppflags.join(" ")}"
62
82
  $LDFLAGS += " #{@ldflags.join(" ")}"
63
83
  $CPPFLAGS += " -fPIC"
@@ -0,0 +1,40 @@
1
+ #include "imageprovidertest.h"
2
+ #include <QQuickImageProvider>
3
+ #include <QCoreApplication>
4
+ #include <future>
5
+ #include <atomic>
6
+
7
+ namespace RubyQml {
8
+
9
+ ImageProviderTest::ImageProviderTest(QObject *parent) :
10
+ QObject(parent)
11
+ {
12
+ }
13
+
14
+ bool ImageProviderTest::requestAndCompare(QObject *imageProvider, const QString &id, const QByteArray &imageData)
15
+ {
16
+ auto provider = dynamic_cast<QQuickImageProvider *>(imageProvider);
17
+ if (!provider) {
18
+ throw std::runtime_error("invalid iamge provider");
19
+ }
20
+ std::atomic_bool finished(false);
21
+ auto result = std::async(std::launch::async, [=, &finished] {
22
+ QSize size;
23
+ auto result = provider->requestImage(id, &size, QSize());
24
+ finished = true;
25
+ return result;
26
+ });
27
+ auto start = std::chrono::steady_clock::now();
28
+ while (!finished) {
29
+ QCoreApplication::processEvents();
30
+ auto current = std::chrono::steady_clock::now();
31
+ if (current - start > std::chrono::seconds(1)) {
32
+ throw std::runtime_error("image request timeout");
33
+ }
34
+ }
35
+ auto actual = result.get();
36
+ auto expected = QImage::fromData(imageData);
37
+ return actual == expected;
38
+ }
39
+
40
+ }
@@ -0,0 +1,17 @@
1
+ #pragma once
2
+
3
+ #include <QObject>
4
+
5
+ namespace RubyQml {
6
+
7
+ class ImageProviderTest : public QObject
8
+ {
9
+ Q_OBJECT
10
+ public:
11
+ explicit ImageProviderTest(QObject *parent = 0);
12
+
13
+ public slots:
14
+ bool requestAndCompare(QObject *imageProvider, const QString &id, const QByteArray &imageData);
15
+ };
16
+
17
+ }
@@ -1,6 +1,6 @@
1
1
  TEMPLATE = lib
2
2
  CONFIG += plugin c++11
3
- QT += qml
3
+ QT += qml quick
4
4
 
5
5
  TARGET = rubyqml-testutil
6
6
  INCLUDEPATH += .
@@ -10,11 +10,13 @@ SOURCES += testobject.cpp \
10
10
  testobjectsubclass.cpp \
11
11
  ownershiptest.cpp \
12
12
  testutilplugin.cpp \
13
- objectlifechecker.cpp
13
+ objectlifechecker.cpp \
14
+ imageprovidertest.cpp
14
15
 
15
16
  HEADERS += \
16
17
  testobject.h \
17
18
  testobjectsubclass.h \
18
19
  ownershiptest.h \
19
20
  testutilplugin.h \
20
- objectlifechecker.h
21
+ objectlifechecker.h \
22
+ imageprovidertest.h
@@ -3,7 +3,9 @@
3
3
  #include "testobjectsubclass.h"
4
4
  #include "ownershiptest.h"
5
5
  #include "objectlifechecker.h"
6
+ #include "imageprovidertest.h"
6
7
  #include <QtQml>
8
+ #include <QQuickWindow>
7
9
 
8
10
  Q_DECLARE_METATYPE(const QMetaObject*)
9
11
 
@@ -17,6 +19,7 @@ TestUtilPlugin::TestUtilPlugin(QObject *parent) :
17
19
  qRegisterMetaType<TestObjectSubclass *>();
18
20
  qRegisterMetaType<OwnershipTest *>();
19
21
  qRegisterMetaType<ObjectLifeChecker *>();
22
+ qRegisterMetaType<ImageProviderTest *>();
20
23
 
21
24
  auto metaObjects = { &TestObject::staticMetaObject, &ObjectLifeChecker::staticMetaObject};
22
25
  for (auto metaobj : metaObjects) {
@@ -44,4 +47,9 @@ ObjectLifeChecker *TestUtilPlugin::createObjectLifeChecker(QObject *target)
44
47
  return new ObjectLifeChecker(target);
45
48
  }
46
49
 
50
+ ImageProviderTest *TestUtilPlugin::createImageProviderTest()
51
+ {
52
+ return new ImageProviderTest();
53
+ }
54
+
47
55
  } // namespace RubyQml
@@ -2,12 +2,15 @@
2
2
  #include <QObject>
3
3
  #include <QVariant>
4
4
 
5
+ class QQuickWindow;
6
+
5
7
  namespace RubyQml {
6
8
 
7
9
  class TestObject;
8
10
  class TestObjectSubclass;
9
11
  class OwnershipTest;
10
12
  class ObjectLifeChecker;
13
+ class ImageProviderTest;
11
14
 
12
15
  class TestUtilPlugin : public QObject
13
16
  {
@@ -24,6 +27,7 @@ public slots:
24
27
  RubyQml::TestObjectSubclass *createTestObjectSubclass();
25
28
  RubyQml::OwnershipTest *createOwnershipTest();
26
29
  RubyQml::ObjectLifeChecker *createObjectLifeChecker(QObject *target);
30
+ RubyQml::ImageProviderTest *createImageProviderTest();
27
31
 
28
32
  private:
29
33
  QVariantHash mMetaObjects;
data/lib/qml/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module QML
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
data/qml.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["iofg2100@gmail.com"]
11
11
  spec.summary = %q{A QML / Qt Quick wrapper for Ruby}
12
12
  spec.description = "ruby-qml provides bindings between QML and Ruby and enables you to use Qt Quick-based GUI from Ruby."
13
- spec.homepage = "https://github.com/seanchas116/ruby-qml"
13
+ spec.homepage = "http://seanchas116.github.io/ruby-qml/"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
Binary file
@@ -2,9 +2,24 @@ require 'spec_helper'
2
2
 
3
3
  describe QML::Application do
4
4
  let(:application) { QML.application }
5
- describe '.instance' do
6
- it 'returns the QML::Application instance' do
7
- expect(application).to be_a(QML::Application)
5
+
6
+ describe '.new' do
7
+ it 'fails with QML::ApplicationError' do
8
+ expect { QML::Application.new }.to raise_error(QML::ApplicationError)
9
+ end
10
+ end
11
+ describe '.notify_error' do
12
+ let(:error) do
13
+ begin
14
+ fail "hoge"
15
+ rescue => e
16
+ e
17
+ end
18
+ end
19
+
20
+ it 'prints an error to stderr' do
21
+ expect { QML::Application.notify_error(error) }
22
+ .to output(/#{error.message}/).to_stderr
8
23
  end
9
24
  end
10
25
  describe '#engine' do
@@ -41,3 +56,11 @@ describe QML::Application do
41
56
  end
42
57
  end
43
58
  end
59
+
60
+ describe QML do
61
+ describe '.application' do
62
+ it 'returns the QML::Application instance' do
63
+ expect(QML.application).to be_a(QML::Application)
64
+ end
65
+ end
66
+ end
@@ -41,4 +41,12 @@ describe QML::Component do
41
41
  end
42
42
  end
43
43
  end
44
+
45
+ describe '#initialize' do
46
+ context 'when neither string nor path specified' do
47
+ it 'fails with QMLError' do
48
+ expect { QML::Component.new({}) }.to raise_error(QML::QMLError)
49
+ end
50
+ end
51
+ end
44
52
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe QML::Engine do
4
+ describe '.new' do
5
+ it 'fails with QML::EngineError' do
6
+ expect { QML::Engine.new }.to raise_error(QML::EngineError)
7
+ end
8
+ end
9
+ end
10
+
11
+ describe QML do
12
+ describe '.engine' do
13
+ it 'returns the instance of QML::Engine' do
14
+ expect(QML.engine).to be_a(QML::Engine)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe QML::ImageProvider do
4
+
5
+ describe '#request' do
6
+ it 'is not implemented by default' do
7
+ expect { QML::ImageProvider.new.request(nil) }.to raise_error(NotImplementedError)
8
+ end
9
+ end
10
+
11
+ context 'with test image' do
12
+ let(:klass) do
13
+ Class.new QML::ImageProvider do
14
+ attr_reader :image
15
+
16
+ def initialize
17
+ @image = (Pathname(__FILE__) + '../../assets/test.png').binread
18
+ super
19
+ end
20
+
21
+ def request(req)
22
+ req.finish(image)
23
+ end
24
+ end
25
+ end
26
+ let(:image_provider) { klass.new }
27
+
28
+ it 'provides image to QML' do
29
+ test = QML::Plugins.test_util.create_image_provider_test
30
+ expect(test.request_and_compare(image_provider.qt_image_provider, 'test', image_provider.image)).to eq true
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe QML::Wrappable do
4
+ describe '#create_wrapper' do
5
+ it 'is not implemented by default' do
6
+ obj = Class.new { include QML::Wrappable }.new
7
+ expect { obj.create_wrapper }.to raise_error(NotImplementedError)
8
+ end
9
+ end
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryohei Ikegami
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-24 00:00:00.000000000 Z
11
+ date: 2014-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -209,6 +209,8 @@ files:
209
209
  - ext/qml/plugins/core/imagerequestpromise.h
210
210
  - ext/qml/plugins/core/qmlexception.cpp
211
211
  - ext/qml/plugins/core/qmlexception.h
212
+ - ext/qml/plugins/testutil/imageprovidertest.cpp
213
+ - ext/qml/plugins/testutil/imageprovidertest.h
212
214
  - ext/qml/plugins/testutil/objectlifechecker.cpp
213
215
  - ext/qml/plugins/testutil/objectlifechecker.h
214
216
  - ext/qml/plugins/testutil/ownershiptest.cpp
@@ -286,6 +288,7 @@ files:
286
288
  - lib/qml/version.rb
287
289
  - lib/qml/wrappable.rb
288
290
  - qml.gemspec
291
+ - spec/assets/test.png
289
292
  - spec/assets/testobj.qml
290
293
  - spec/qml/access_spec.rb
291
294
  - spec/qml/application_spec.rb
@@ -297,9 +300,11 @@ files:
297
300
  - spec/qml/data/query_model_spec.rb
298
301
  - spec/qml/dispatchable_spec.rb
299
302
  - spec/qml/dispatcher_spec.rb
303
+ - spec/qml/engine_spec.rb
300
304
  - spec/qml/geometry/point_spec.rb
301
305
  - spec/qml/geometry/rectangle_spec.rb
302
306
  - spec/qml/geometry/size_spec.rb
307
+ - spec/qml/image_provider_spec.rb
303
308
  - spec/qml/plugin_loader_spec.rb
304
309
  - spec/qml/qt_object_base_spec.rb
305
310
  - spec/qml/reactive/object_spec.rb
@@ -307,10 +312,11 @@ files:
307
312
  - spec/qml/reactive/signal_spec.rb
308
313
  - spec/qml/reactive/signal_spy_spec.rb
309
314
  - spec/qml/test_object_spec.rb
315
+ - spec/qml/wrappable_spec.rb
310
316
  - spec/qml_spec.rb
311
317
  - spec/shared_examples/qml/data/list_model.rb
312
318
  - spec/spec_helper.rb
313
- homepage: https://github.com/seanchas116/ruby-qml
319
+ homepage: http://seanchas116.github.io/ruby-qml/
314
320
  licenses:
315
321
  - MIT
316
322
  metadata: {}
@@ -335,6 +341,7 @@ signing_key:
335
341
  specification_version: 4
336
342
  summary: A QML / Qt Quick wrapper for Ruby
337
343
  test_files:
344
+ - spec/assets/test.png
338
345
  - spec/assets/testobj.qml
339
346
  - spec/qml/access_spec.rb
340
347
  - spec/qml/application_spec.rb
@@ -346,9 +353,11 @@ test_files:
346
353
  - spec/qml/data/query_model_spec.rb
347
354
  - spec/qml/dispatchable_spec.rb
348
355
  - spec/qml/dispatcher_spec.rb
356
+ - spec/qml/engine_spec.rb
349
357
  - spec/qml/geometry/point_spec.rb
350
358
  - spec/qml/geometry/rectangle_spec.rb
351
359
  - spec/qml/geometry/size_spec.rb
360
+ - spec/qml/image_provider_spec.rb
352
361
  - spec/qml/plugin_loader_spec.rb
353
362
  - spec/qml/qt_object_base_spec.rb
354
363
  - spec/qml/reactive/object_spec.rb
@@ -356,6 +365,7 @@ test_files:
356
365
  - spec/qml/reactive/signal_spec.rb
357
366
  - spec/qml/reactive/signal_spy_spec.rb
358
367
  - spec/qml/test_object_spec.rb
368
+ - spec/qml/wrappable_spec.rb
359
369
  - spec/qml_spec.rb
360
370
  - spec/shared_examples/qml/data/list_model.rb
361
371
  - spec/spec_helper.rb