lucian 0.1.0 → 0.1.2dev
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.
- checksums.yaml +4 -4
- data/Guardfile +70 -0
- data/README.md +2 -1
- data/exe/lucian +23 -1
- data/lib/docker/compose/session.rb +5 -0
- data/lib/lucian/board_caster.rb +25 -0
- data/lib/lucian/engine.rb +156 -0
- data/lib/lucian/errors.rb +3 -0
- data/lib/lucian/initiator.rb +40 -0
- data/lib/lucian/template/Dockerfile +19 -0
- data/lib/lucian/template/Gemfile +3 -0
- data/lib/lucian/template/lucian_helper.rb +4 -0
- data/lib/lucian/version.rb +1 -1
- data/lib/lucian.rb +60 -2
- data/lib/rspec/core/configuration.rb +16 -0
- data/lib/rspec/core/configuration_options.rb +7 -0
- data/lib/rspec/core/example.rb +74 -0
- data/lib/rspec/core/example_group.rb +58 -0
- data/lib/rspec/core/runner.rb +35 -0
- data/lib/rspec.rb +11 -0
- data/lucian.gemspec +21 -12
- metadata +107 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a70326cadccfdeb97913d4c115c4adb4e98c819
|
4
|
+
data.tar.gz: aa85e7cb5f82de057717260e3782f236702d53ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e58e22aba46a882e0528c06a14d248878164b7addb91066b56a2096f5b02c58b262e11d27e21e8effd7a72ab9db4713d486b8b833583b2913dae903f8965aef0
|
7
|
+
data.tar.gz: 24dcf63d594ae64810e5b1d15b0b22c951bd2290c22eefb89edb126a298d861321507ba9bf10253e51d8d28907c3c615b9f45d9bfb46557dd7731c1f61912274
|
data/Guardfile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
28
|
+
require "guard/rspec/dsl"
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
30
|
+
|
31
|
+
# Feel free to open issues for suggestions and improvements
|
32
|
+
|
33
|
+
# RSpec files
|
34
|
+
rspec = dsl.rspec
|
35
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
36
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
37
|
+
watch(rspec.spec_files)
|
38
|
+
|
39
|
+
# Ruby files
|
40
|
+
ruby = dsl.ruby
|
41
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
+
|
43
|
+
# Rails files
|
44
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
45
|
+
dsl.watch_spec_files_for(rails.app_files)
|
46
|
+
dsl.watch_spec_files_for(rails.views)
|
47
|
+
|
48
|
+
watch(rails.controllers) do |m|
|
49
|
+
[
|
50
|
+
rspec.spec.call("routing/#{m[1]}_routing"),
|
51
|
+
rspec.spec.call("controllers/#{m[1]}_controller"),
|
52
|
+
rspec.spec.call("acceptance/#{m[1]}")
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Rails config changes
|
57
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
58
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
59
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
60
|
+
|
61
|
+
# Capybara features specs
|
62
|
+
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
|
63
|
+
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
|
64
|
+
|
65
|
+
# Turnip features and steps
|
66
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
67
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
68
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
69
|
+
end
|
70
|
+
end
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
[](https://github.com/gastzars/lucian)
|
2
|
+
[](https://github.com/gastzars/lucian)
|
2
3
|
|
3
4
|
[](https://travis-ci.org/gastzars/lucian)
|
4
5
|
|
data/exe/lucian
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
|
-
# exe/
|
3
|
+
# exe/lucian
|
4
4
|
|
5
5
|
# $: is just a shortcut for $LOAD_PATH. __FILE__ is the relative
|
6
6
|
# path to the script. This adds the current script directory
|
@@ -9,3 +9,25 @@
|
|
9
9
|
this_file = Pathname.new(__FILE__).realpath
|
10
10
|
$:.unshift File.expand_path("../../lib", this_file)
|
11
11
|
require 'lucian'
|
12
|
+
require 'rspec/core'
|
13
|
+
require 'optparse'
|
14
|
+
|
15
|
+
options = {}
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: lucian [options]"
|
18
|
+
|
19
|
+
opts.on("-i", "--init", "Initialize Lucian environment") do |v|
|
20
|
+
options[:init] = v
|
21
|
+
Lucian::Initiator.init
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("-eSTRING", "--example=STRING", "Run examples whose full nested names include STRING") do |v|
|
25
|
+
(options[:example] ||= []) << Regexp.compile(Regexp.escape(v))
|
26
|
+
end
|
27
|
+
end.parse!
|
28
|
+
|
29
|
+
if options[:init].nil?
|
30
|
+
lucian = Lucian::Engine.new(nil, options[:example])
|
31
|
+
lucian.run
|
32
|
+
lucian.shutdown
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Lucian
|
2
|
+
module BoardCaster
|
3
|
+
def self.print(message, color=nil)
|
4
|
+
color_code = case color
|
5
|
+
when "red"
|
6
|
+
31
|
7
|
+
when "green"
|
8
|
+
32
|
9
|
+
when "yellow"
|
10
|
+
33
|
11
|
+
when "blue"
|
12
|
+
34
|
13
|
+
when "pink"
|
14
|
+
35
|
15
|
+
when "cyan"
|
16
|
+
36
|
17
|
+
when "gray"
|
18
|
+
37
|
19
|
+
else
|
20
|
+
0
|
21
|
+
end
|
22
|
+
puts "\e[#{color_code}m#{message}\e[0m"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module Lucian
|
2
|
+
|
3
|
+
##
|
4
|
+
# Core module for Lucian framework is HERE !
|
5
|
+
class Engine
|
6
|
+
attr_reader :compose_file, :compose_data, :compose_directory, :network_name #lucian_files
|
7
|
+
|
8
|
+
attr_reader :docker_compose, :network_name, :examples
|
9
|
+
|
10
|
+
##
|
11
|
+
# Initialize and fetch for compose file.
|
12
|
+
# if unable to find a docker-compose file then givving an error
|
13
|
+
def initialize(compose_file = nil, examples = [])
|
14
|
+
@compose_file = compose_file || fetch_docker_compose_file
|
15
|
+
raise Error.new('Unable to find docker-compose.yml or docker-compose.yaml.') if !@compose_file || !File.file?(@compose_file)
|
16
|
+
@compose_directory = File.expand_path(@compose_file+'/..')
|
17
|
+
@compose_data = YAML.load_file(@compose_file)
|
18
|
+
@lucian_directory = @compose_directory+'/'+DIRECTORY
|
19
|
+
@lucian_helper = @lucian_directory+'/'+HELPER
|
20
|
+
#@lucian_files = fetch_lucian_files(@lucian_directory)
|
21
|
+
@network_name = File.basename(@compose_directory).gsub!(/[^0-9A-Za-z]/, '')
|
22
|
+
$LOAD_PATH.unshift(@lucian_directory) unless $LOAD_PATH.include?(@lucian_directory)
|
23
|
+
@docker_compose = Docker::Compose.new
|
24
|
+
@examples = examples
|
25
|
+
config_compose
|
26
|
+
require 'lucian_helper' if File.exist?(@lucian_helper)
|
27
|
+
Lucian.engine = self
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Run
|
32
|
+
def run
|
33
|
+
BoardCaster.print("Start running Lucian ..", "yellow")
|
34
|
+
RSpec.lucian_engine = self
|
35
|
+
Lucian::Runner.invoke(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Shutdown
|
40
|
+
def shutdown
|
41
|
+
@docker_compose.down
|
42
|
+
stop_lucian_container
|
43
|
+
remove_lucian_container
|
44
|
+
# remove_lucian_image # NOTE Bot sure we need to remove this or not
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Run and validate services status
|
49
|
+
def run_docker_service(services_names)
|
50
|
+
services_names.collect!(&:to_s)
|
51
|
+
services_names.each do |service|
|
52
|
+
@docker_compose.up(service, {:detached => true})
|
53
|
+
end
|
54
|
+
exited = @docker_compose.ps.where { |c| !c.up? && services_names.include?(c.image) }
|
55
|
+
raise "We have some exited containers: " + exited.join(', ') if exited.count > 0
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Stop docker service
|
60
|
+
def stop_docker_service(services_names)
|
61
|
+
services_names.each do |service|
|
62
|
+
@docker_compose.stop(service)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Start lucian docker connect to compose
|
68
|
+
def start_lucian_docker
|
69
|
+
image = build_lucian_image
|
70
|
+
run_lucian_image(image)
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
##
|
77
|
+
# Config compose
|
78
|
+
def config_compose
|
79
|
+
@docker_compose.file = @compose_file
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Fetching compose file from curent directory and parents
|
84
|
+
def fetch_docker_compose_file(path = File.expand_path('.'))
|
85
|
+
files = Dir.glob(path+'/docker-compose.y*ml')
|
86
|
+
files = fetch_docker_compose_file(File.expand_path(path+'/..')) if files.size == 0 && path != '/'
|
87
|
+
if files.instance_of?(Array)
|
88
|
+
compose_path = files[0]
|
89
|
+
else
|
90
|
+
compose_path = files
|
91
|
+
end
|
92
|
+
return compose_path
|
93
|
+
end
|
94
|
+
|
95
|
+
## NOTE CURRENTLY UNUSED
|
96
|
+
#
|
97
|
+
# Fetching *_lucian.rb files
|
98
|
+
#
|
99
|
+
#def fetch_lucian_files(path = File.expand_path('./lucian'))
|
100
|
+
# Dir.glob("#{path}/**/*_lucian.rb")
|
101
|
+
#end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Build lucian docker image
|
105
|
+
def build_lucian_image
|
106
|
+
BoardCaster.print("Building lucian image ..", "yellow")
|
107
|
+
image = Docker::Image.build_from_dir(@lucian_directory)
|
108
|
+
Lucian.image = image
|
109
|
+
return image
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Run lucian docker image
|
114
|
+
def run_lucian_image(image=Lucian.image)
|
115
|
+
raise "Image can not be nil" if image.nil?
|
116
|
+
BoardCaster.print("Starting lucian container ..", "yellow")
|
117
|
+
container = image.run
|
118
|
+
Lucian.container = container
|
119
|
+
return container
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Remove docker image
|
124
|
+
def remove_lucian_image(image=Lucian.image)
|
125
|
+
raise "Image can not be nil" if image.nil?
|
126
|
+
BoardCaster.print("Removing lucian image ..", "yellow")
|
127
|
+
image.remove
|
128
|
+
return true
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Remove docker container
|
133
|
+
def remove_lucian_container(container=Lucian.container)
|
134
|
+
raise "Container can not be nil" if container.nil?
|
135
|
+
BoardCaster.print("Removing lucian contanier ..", "yellow")
|
136
|
+
container.remove
|
137
|
+
return true
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Stop docker container
|
142
|
+
def stop_lucian_container(container=Lucian.container)
|
143
|
+
raise "Container can not be nil" if container.nil?
|
144
|
+
BoardCaster.print("Stopping lucian contanier ..", "yellow")
|
145
|
+
container.kill!
|
146
|
+
return true
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Run lucian test
|
151
|
+
def run_lucian_test(example)
|
152
|
+
container.exec('lucian', '--example', "\"#{example}\"")
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Lucian
|
4
|
+
##
|
5
|
+
# Initiator module for initializing process
|
6
|
+
|
7
|
+
module Initiator
|
8
|
+
def self.init(path = File.expand_path('.'))
|
9
|
+
BoardCaster.print('Start initialize Lucian environment', "green")
|
10
|
+
lucian_path = File.expand_path(path+'/lucian')
|
11
|
+
create_directory(lucian_path)
|
12
|
+
create_helper_file(lucian_path)
|
13
|
+
create_gemfile(lucian_path)
|
14
|
+
create_dockerfile(lucian_path)
|
15
|
+
BoardCaster.print('Lucian init DONE', "green")
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def self.create_directory(directory_path)
|
21
|
+
FileUtils::mkdir_p directory_path
|
22
|
+
BoardCaster.print('Create: '+directory_path+' [DONE]', "yellow")
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.create_helper_file(directory_path)
|
26
|
+
FileUtils.cp(File.expand_path(File.expand_path(__FILE__)+'./../template/lucian_helper.rb'), directory_path)
|
27
|
+
BoardCaster.print('Create: '+directory_path+'/lucian_helper.rb'+' [DONE]', "yellow")
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.create_gemfile(directory_path)
|
31
|
+
FileUtils.cp(File.expand_path(File.expand_path(__FILE__)+'./../template/Gemfile'), directory_path)
|
32
|
+
BoardCaster.print('Create: '+directory_path+'/Gemfile'+' [DONE]', "yellow")
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.create_dockerfile(directory_path)
|
36
|
+
FileUtils.cp(File.expand_path(File.expand_path(__FILE__)+'./../template/Dockerfile'), directory_path)
|
37
|
+
BoardCaster.print('Create: '+directory_path+'/Dockerfile'+' [DONE]', "yellow")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
FROM ruby:2.3.1
|
2
|
+
|
3
|
+
RUN apt-get update
|
4
|
+
|
5
|
+
# Prepare work directory
|
6
|
+
RUN mkdir /app
|
7
|
+
RUN mkdir /app/lucian
|
8
|
+
WORKDIR /app
|
9
|
+
ADD Gemfile /app/Gemfile
|
10
|
+
|
11
|
+
# Bundle install rails's gem bundle
|
12
|
+
RUN bundle install
|
13
|
+
|
14
|
+
# Add application directory
|
15
|
+
ADD . /app/lucian
|
16
|
+
|
17
|
+
ENV LUCIAN_DOCKER=true
|
18
|
+
|
19
|
+
CMD tail -f /dev/null
|
data/lib/lucian/version.rb
CHANGED
data/lib/lucian.rb
CHANGED
@@ -1,5 +1,63 @@
|
|
1
|
-
require
|
1
|
+
require 'lucian/version'
|
2
|
+
require 'docker/compose'
|
3
|
+
require 'rspec/core'
|
4
|
+
require 'docker-api'
|
5
|
+
|
6
|
+
require_relative 'lucian/engine'
|
7
|
+
require_relative 'lucian/errors'
|
8
|
+
require_relative 'lucian/initiator'
|
9
|
+
require_relative 'lucian/board_caster'
|
10
|
+
require_relative 'rspec'
|
11
|
+
require_relative 'rspec/core/example_group'
|
12
|
+
require_relative 'rspec/core/example'
|
13
|
+
require_relative 'rspec/core/configuration'
|
14
|
+
require_relative 'rspec/core/configuration_options'
|
15
|
+
require_relative 'rspec/core/runner'
|
16
|
+
require_relative 'docker/compose/session'
|
2
17
|
|
3
18
|
module Lucian
|
4
|
-
|
19
|
+
DIRECTORY = 'lucian'
|
20
|
+
HELPER = 'lucian_helper.rb'
|
21
|
+
|
22
|
+
include RSpec::Core
|
23
|
+
|
24
|
+
# Reinitialize core syntax
|
25
|
+
|
26
|
+
RSpec::Core::ExampleGroup.define_example_method :example
|
27
|
+
RSpec::Core::ExampleGroup.define_example_method :it
|
28
|
+
RSpec::Core::ExampleGroup.define_example_method :specify
|
29
|
+
RSpec::Core::ExampleGroup.define_example_method :focus, :focus => true
|
30
|
+
RSpec::Core::ExampleGroup.define_example_method :fexample, :focus => true
|
31
|
+
RSpec::Core::ExampleGroup.define_example_method :fit, :focus => true
|
32
|
+
RSpec::Core::ExampleGroup.define_example_method :fspecify, :focus => true
|
33
|
+
RSpec::Core::ExampleGroup.define_example_method :xexample, :skip => 'Temporarily skipped with xexample'
|
34
|
+
RSpec::Core::ExampleGroup.define_example_method :xit, :skip => 'Temporarily skipped with xit'
|
35
|
+
RSpec::Core::ExampleGroup.define_example_method :xspecify, :skip => 'Temporarily skipped with xspecify'
|
36
|
+
RSpec::Core::ExampleGroup.define_example_method :skip, :skip => true
|
37
|
+
RSpec::Core::ExampleGroup.define_example_method :pending, :pending => true
|
38
|
+
|
39
|
+
RSpec::Core::ExampleGroup.define_example_group_method :example_group
|
40
|
+
RSpec::Core::ExampleGroup.define_example_group_method :describe
|
41
|
+
RSpec::Core::ExampleGroup.define_example_group_method :context
|
42
|
+
RSpec::Core::ExampleGroup.define_example_group_method :xdescribe, :skip => "Temporarily skipped with xdescribe"
|
43
|
+
RSpec::Core::ExampleGroup.define_example_group_method :xcontext, :skip => "Temporarily skipped with xcontext"
|
44
|
+
RSpec::Core::ExampleGroup.define_example_group_method :fdescribe, :focus => true
|
45
|
+
RSpec::Core::ExampleGroup.define_example_group_method :fcontext, :focus => true
|
46
|
+
|
47
|
+
##
|
48
|
+
# Start lucian docker
|
49
|
+
def self.start_lucian_docker
|
50
|
+
engine.start_lucian_docker
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Run lucian test
|
55
|
+
def self.run_lucian_test(example)
|
56
|
+
engine.run_lucian_test(example)
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
attr_accessor :engine, :image, :container
|
61
|
+
end
|
5
62
|
end
|
63
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RSpec::Core
|
2
|
+
class Configuration
|
3
|
+
def files_or_directories_to_run=(*files)
|
4
|
+
files = files.flatten
|
5
|
+
|
6
|
+
if (command == 'rspec' || Runner.running_in_drb?) && default_path && files.empty?
|
7
|
+
files << default_path
|
8
|
+
elsif command == 'lucian'
|
9
|
+
files << 'lucian'
|
10
|
+
end
|
11
|
+
|
12
|
+
@files_or_directories_to_run = files
|
13
|
+
@files_to_run = nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module RSpec::Core
|
2
|
+
class Example
|
3
|
+
def run(example_group_instance, reporter)
|
4
|
+
@example_group_instance = example_group_instance
|
5
|
+
@reporter = reporter
|
6
|
+
RSpec.configuration.configure_example(self, hooks)
|
7
|
+
RSpec.current_example = self
|
8
|
+
|
9
|
+
start(reporter)
|
10
|
+
Pending.mark_pending!(self, pending) if pending?
|
11
|
+
|
12
|
+
begin
|
13
|
+
if skipped?
|
14
|
+
Pending.mark_pending! self, skip
|
15
|
+
elsif !RSpec.configuration.dry_run?
|
16
|
+
with_around_and_singleton_context_hooks do
|
17
|
+
begin
|
18
|
+
# NOTE Code is overrided HERE
|
19
|
+
# Check if there are services or not
|
20
|
+
if self.metadata[:services] != nil && self.metadata[:services].is_a?(Array) && ENV["LUCIAN_DOCKER"] == nil
|
21
|
+
run_docker_services
|
22
|
+
run_lucian_test
|
23
|
+
else
|
24
|
+
run_before_example
|
25
|
+
@example_group_instance.instance_exec(self, &@example_block)
|
26
|
+
|
27
|
+
if pending?
|
28
|
+
Pending.mark_fixed! self
|
29
|
+
|
30
|
+
raise Pending::PendingExampleFixedError,
|
31
|
+
'Expected example to fail since it is pending, but it passed.',
|
32
|
+
[location]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
rescue Pending::SkipDeclaredInExample
|
36
|
+
# no-op, required metadata has already been set by the `skip`
|
37
|
+
# method.
|
38
|
+
rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
|
39
|
+
set_exception(e)
|
40
|
+
ensure
|
41
|
+
run_after_example
|
42
|
+
stop_docker_services if self.metadata[:services] != nil && self.metadata[:services].is_a?(Array) && ENV["LUCIAN_DOCKER"] == nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
|
47
|
+
set_exception(e)
|
48
|
+
ensure
|
49
|
+
@example_group_instance = nil # if you love something... let it go
|
50
|
+
end
|
51
|
+
|
52
|
+
finish(reporter)
|
53
|
+
ensure
|
54
|
+
execution_result.ensure_timing_set(clock)
|
55
|
+
RSpec.current_example = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_docker_services
|
59
|
+
Lucian::BoardCaster.print("\n>> ExampleGroup : "+self.metadata[:full_description].to_s, "cyan")
|
60
|
+
RSpec.lucian_engine.run_docker_service(self.metadata[:services])
|
61
|
+
end
|
62
|
+
|
63
|
+
def stop_docker_services
|
64
|
+
RSpec.lucian_engine.stop_docker_service(self.metadata[:services])
|
65
|
+
end
|
66
|
+
|
67
|
+
def run_lucian_test
|
68
|
+
if Lucian.image.nil? || Lucian.container.nil?
|
69
|
+
Lucian.start_lucian_docker
|
70
|
+
end
|
71
|
+
Lucian.run_lucian_test(self.metadata[:full_description].to_s)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module RSpec::Core
|
2
|
+
class ExampleGroup
|
3
|
+
|
4
|
+
def self.define_example_method(name, extra_options={})
|
5
|
+
idempotently_define_singleton_method(name) do |*all_args, &block|
|
6
|
+
# NOTE EXAMPLE METHOD IS OVERRIDED HERE
|
7
|
+
|
8
|
+
desc, *args = *all_args
|
9
|
+
options = Metadata.build_hash_from(args)
|
10
|
+
options.update(:skip => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block
|
11
|
+
options.update(extra_options)
|
12
|
+
|
13
|
+
RSpec::Core::Example.new(self, desc, options, block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.define_example_group_method(name, metadata={})
|
18
|
+
idempotently_define_singleton_method(name) do |*args, &example_group_block|
|
19
|
+
# NOTE EXAMPLE GROUP METHOD IS OVERRIDED HERE
|
20
|
+
|
21
|
+
|
22
|
+
# END OVERRIDED HERE
|
23
|
+
|
24
|
+
thread_data = RSpec::Support.thread_local_data
|
25
|
+
top_level = self == ExampleGroup
|
26
|
+
|
27
|
+
registration_collection =
|
28
|
+
if top_level
|
29
|
+
if thread_data[:in_example_group]
|
30
|
+
raise "Creating an isolated context from within a context is " \
|
31
|
+
"not allowed. Change `RSpec.#{name}` to `#{name}` or " \
|
32
|
+
"move this to a top-level scope."
|
33
|
+
end
|
34
|
+
|
35
|
+
thread_data[:in_example_group] = true
|
36
|
+
RSpec.world.example_groups
|
37
|
+
else
|
38
|
+
children
|
39
|
+
end
|
40
|
+
|
41
|
+
begin
|
42
|
+
description = args.shift
|
43
|
+
combined_metadata = metadata.dup
|
44
|
+
combined_metadata.merge!(args.pop) if args.last.is_a? Hash
|
45
|
+
args << combined_metadata
|
46
|
+
|
47
|
+
subclass(self, description, args, registration_collection, &example_group_block)
|
48
|
+
ensure
|
49
|
+
thread_data.delete(:in_example_group) if top_level
|
50
|
+
|
51
|
+
# OVERRIDED ENSURE
|
52
|
+
#
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RSpec::Core
|
2
|
+
class Runner
|
3
|
+
def self.invoke(lucian_engine=nil)
|
4
|
+
disable_autorun!
|
5
|
+
status = run(ARGV, $stderr, $stdout, lucian_engine).to_i
|
6
|
+
exit(status) if status != 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.run(args, err=$stderr, out=$stdout, lucian_engine=nil)
|
10
|
+
trap_interrupt
|
11
|
+
options = ConfigurationOptions.new(args)
|
12
|
+
|
13
|
+
if options.options[:runner]
|
14
|
+
options.options[:runner].call(options, err, out)
|
15
|
+
else
|
16
|
+
if lucian_engine
|
17
|
+
options.options[:full_description] = lucian_engine.examples if !lucian_engine.examples.nil? && lucian_engine.examples.count > 0
|
18
|
+
new(options, RSpec.configuration, RSpec.world, lucian_engine).run(err, out)
|
19
|
+
else
|
20
|
+
new(options).run(err, out)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(options, configuration=RSpec.configuration, world=RSpec.world, lucian_engine=nil)
|
26
|
+
@options = options
|
27
|
+
@configuration = configuration
|
28
|
+
if lucian_engine
|
29
|
+
configuration.pattern = "**{,/*/**}/*_lucian.rb"
|
30
|
+
end
|
31
|
+
@world = world
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/rspec.rb
ADDED
data/lucian.gemspec
CHANGED
@@ -4,24 +4,33 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'lucian/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'lucian'
|
8
8
|
spec.version = Lucian::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Tanapat Sainak']
|
10
|
+
spec.email = ['tanapat@computerlogy.com']
|
11
11
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
|
15
|
-
|
12
|
+
spec.summary = 'Lucian is a test framework for Docker environments using docker-compose.'
|
13
|
+
spec.description = 'Lucian is a test framework for Docker environments '\
|
14
|
+
'which running up containers using docker-compose.yml, '\
|
15
|
+
'and testing them using Rspec.'
|
16
|
+
spec.homepage = 'https://github.com/gastzars/lucian'
|
17
|
+
spec.license = 'MIT'
|
16
18
|
|
17
19
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
20
|
f.match(%r{^(test|spec|features)/})
|
19
21
|
end
|
20
|
-
spec.bindir =
|
22
|
+
spec.bindir = 'exe'
|
21
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = [
|
24
|
+
spec.require_paths = ['lib']
|
23
25
|
|
24
|
-
spec.add_runtime_dependency(%q<rspec>, [
|
25
|
-
spec.
|
26
|
-
spec.
|
26
|
+
spec.add_runtime_dependency(%q<rspec-expectations>, ['~> 3.0'])
|
27
|
+
spec.add_runtime_dependency(%q<docker-compose>, '~>1.0')
|
28
|
+
spec.add_runtime_dependency(%q<docker-api>, '~>1.30')
|
29
|
+
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
32
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
33
|
+
spec.add_development_dependency 'guard', '~> 2.14'
|
34
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.7'
|
35
|
+
spec.add_development_dependency 'pry'
|
27
36
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lucian
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2dev
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanapat Sainak
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10
|
11
|
+
date: 2016-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: rspec
|
14
|
+
name: rspec-expectations
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
@@ -25,19 +25,47 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: docker-compose
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: docker-api
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.30'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.30'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
68
|
+
version: '3.0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +80,62 @@ dependencies:
|
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.13'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.13'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.14'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.14'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard-rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.7'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.7'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
55
139
|
description: Lucian is a test framework for Docker environments which running up containers
|
56
140
|
using docker-compose.yml, and testing them using Rspec.
|
57
141
|
email:
|
@@ -65,14 +149,29 @@ files:
|
|
65
149
|
- ".rspec"
|
66
150
|
- ".travis.yml"
|
67
151
|
- Gemfile
|
152
|
+
- Guardfile
|
68
153
|
- LICENSE.txt
|
69
154
|
- README.md
|
70
155
|
- Rakefile
|
71
156
|
- bin/console
|
72
157
|
- bin/setup
|
73
158
|
- exe/lucian
|
159
|
+
- lib/docker/compose/session.rb
|
74
160
|
- lib/lucian.rb
|
161
|
+
- lib/lucian/board_caster.rb
|
162
|
+
- lib/lucian/engine.rb
|
163
|
+
- lib/lucian/errors.rb
|
164
|
+
- lib/lucian/initiator.rb
|
165
|
+
- lib/lucian/template/Dockerfile
|
166
|
+
- lib/lucian/template/Gemfile
|
167
|
+
- lib/lucian/template/lucian_helper.rb
|
75
168
|
- lib/lucian/version.rb
|
169
|
+
- lib/rspec.rb
|
170
|
+
- lib/rspec/core/configuration.rb
|
171
|
+
- lib/rspec/core/configuration_options.rb
|
172
|
+
- lib/rspec/core/example.rb
|
173
|
+
- lib/rspec/core/example_group.rb
|
174
|
+
- lib/rspec/core/runner.rb
|
76
175
|
- lucian.gemspec
|
77
176
|
homepage: https://github.com/gastzars/lucian
|
78
177
|
licenses:
|
@@ -89,9 +188,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
188
|
version: '0'
|
90
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
190
|
requirements:
|
92
|
-
- - "
|
191
|
+
- - ">"
|
93
192
|
- !ruby/object:Gem::Version
|
94
|
-
version:
|
193
|
+
version: 1.3.1
|
95
194
|
requirements: []
|
96
195
|
rubyforge_project:
|
97
196
|
rubygems_version: 2.5.1
|