ass_tests 1.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: acb1038346a0074cd225e0b28448550f6dd491dd
4
+ data.tar.gz: 841ebc7201ba1cb6f59843e65001c4fe0d92d9e3
5
+ SHA512:
6
+ metadata.gz: d2aef05c2225fca10ef9d90350516820d7d6d7fc11e77e8132e14610fee9535da19cbe11e38d0eb854837131dbdd9b2ab09d80f4e6d9336aec274b653d584899
7
+ data.tar.gz: 0bbcaf34554b63eb3ac1570fca81213102dff28f28158af8a73303eabe49df4f31177e1b84607cc8648806755cb11e37529319e37445e79a4262e44196889147
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.simplecov ADDED
@@ -0,0 +1 @@
1
+ SimpleCov.start if ENV['SIMPLECOV']
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ before_install: gem install bundler -v 1.10.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ass_tests.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # AssTests
2
+
3
+
4
+ Framework for unit testing code written on [1C:Enterprise](http://1c.ru)
5
+ embedded programming language.
6
+
7
+ It make possible to write tests for 1C:Enterprise on Ruby easy.
8
+
9
+ **Warning! Access to 1C runtime via ```WIN32OLE```. Works only in Windows or Cygwin**
10
+
11
+ ## Benefits
12
+
13
+ - Write tests on Ruby and keep it under ```git``` as text vs write tests on 1C embedded language and keep it as external 1C binary objects.
14
+ - Write tests powered by ```Minitest```, ```RSpec```, ```mocha```, ```cucumber``` and other great Ruby libraries.
15
+ - ```WIN32OLE``` automatically convert Ruby objects into IDispatch objects when it passed as argument on to other side. It make possible passes ```mocha``` ```mock``` objects in to 1C runtime side!!!
16
+
17
+ ## Trouble
18
+
19
+ - Works only in Windows or Cygwin.
20
+ - Not available methods ```eval``` and ```execute``` of 1C "Global context"
21
+ - Unpossible attach to 1C debugger.
22
+ - Now support ```Minitest::Test``` only
23
+ - Other unknown now :(
24
+
25
+ ## Features
26
+
27
+ - Provides DSL for describe 1C:Enterprise application (aka "Information base")
28
+ - Support to describe many different 1C Information bases.
29
+ - Support describe exists Information bases as ```external```. Such Information bases is persistent and can't be build or remove.
30
+ - Automatically build described Information base on demand.
31
+ - Automatically rebuild Information base on demand.
32
+ - Passes required instance of class `InfoBase` into tests for connect to Information base for testing.
33
+ - Hold pool of opened connection with 1C information bases for decrease costs on wakeup 1C application.
34
+ - Automatically close all opened connection after all tests executed.
35
+ - Provides assertions for tests 1C values in Ruby side
36
+ - Provides features for testing of 1C externals like as ExternalDataProcessor and ExternalReport
37
+ - Provides features for fill data in infobases under test.
38
+
39
+ ## Installation
40
+
41
+ Add this line to your application's Gemfile:
42
+
43
+ ```ruby
44
+ gem 'ass_tests'
45
+ ```
46
+
47
+ And then execute:
48
+
49
+ $ bundle
50
+
51
+ Or install it yourself as:
52
+
53
+ $ gem install ass_tests
54
+
55
+ ## Usage
56
+
57
+
58
+ ### Smal example for ```Minitest```
59
+
60
+ - ```test_helper.rb```:
61
+ ```ruby
62
+ require 'ass_tests/autorun'
63
+ require 'ass_tests/info_bases'
64
+
65
+ # Describe empty InfoBase
66
+ AssTests::InfoBases.describe do
67
+ file :empty_ib
68
+ end
69
+ ```
70
+ - ```small_test.rb```:
71
+ ```ruby
72
+
73
+ class SmalTest < AssTests::MiniTest::Test
74
+ # Demands described :empty_ib information base
75
+ use :empty_ib
76
+ # Declare to run :empty_ib in :context of :thick application
77
+ # and we ask keep alive connection while tests executing
78
+ # Default :keep_alive => true.
79
+ # If set :keep_alive => false for :thick or :thin context
80
+ # wakeup connection will be very slowly for big applications
81
+ context :thick, :keep_alive => true
82
+ # If we want login in information base as some user we say:
83
+ # login :as => 'user', :with => 'password'
84
+ # In this example we use empty information base without any users
85
+
86
+ # If we say :keep_alive => true and in tests we want to manipulate
87
+ # with data, each test mast be wrapped in 1C transaction
88
+ # for tests isolation.
89
+ # In this example we aren't manipulate with data
90
+ # Warning! 1C transaction not define for :thin context,
91
+ # for :thin context require patch information base application
92
+ def setup
93
+ ole.BeginTransaction
94
+ end
95
+
96
+ # Transaction mast be rollback for tests isolation
97
+ def teardown
98
+ ole.RollbackTransaction
99
+ end
100
+
101
+ puts infobase.name # => "empty_ib"
102
+ puts infobase.exists? # => "true"
103
+ puts ole.__opened__? # => "false"
104
+ puts ole.class # => "AssLauncher::Enterprise::Ole::ThickApplication"
105
+
106
+ def test_hello_world
107
+ puts ole.__opened__? # => "true"
108
+ a = ole.newObject 'array'
109
+ a.add 'Hello world'
110
+ assert_equal 'Hello world', ole.string(a.get(0))
111
+ end
112
+
113
+ def test_other
114
+ assert ole.__opened__?
115
+ end
116
+ end
117
+ ```
118
+ - also you can write native ```Minitest::Test``` for testing
119
+ other things like this ```ordinary_test.rb```:
120
+ ```ruby
121
+ # Also you can write native Minitest::Test
122
+
123
+ class OrdinaryTest < Minitest::Test
124
+ def test_fail
125
+ assert false
126
+ end
127
+ end
128
+ ```
129
+
130
+ ## Development
131
+
132
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
133
+
134
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
135
+
136
+ ## Contributing
137
+
138
+ Bug reports and pull requests are welcome on GitHub at https://github.com/leoniv/ass_tests.
139
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb'] + FileList['examples/*.rb']
8
+ end
9
+
10
+ task :default => :test
data/ass_tests.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ass_tests/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ass_tests"
8
+ spec.version = AssTests::VERSION
9
+ spec.authors = ["Leonid Vlasov"]
10
+ spec.email = ["leoniv.vlasov@gmail.com"]
11
+
12
+ spec.summary = %q{Framework for unit testing code written on 1C:Enterprise embedded programming language}
13
+ spec.description = %q{It make possible to write tests for 1C:Enterprise on Ruby easy. Access to 1C runtime via OLE. Works only in Windows or Cygwin!!!}
14
+ spec.homepage = "https://github.com/leoniv/ass_tests"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "ass_launcher"
22
+ spec.add_dependency "ass_maintainer-info_base"
23
+ spec.add_dependency "minitest", "> 5"
24
+ spec.add_dependency "minitest-hooks"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.10"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "simplecov"
29
+ spec.add_development_dependency "pry"
30
+ spec.add_development_dependency "mocha"
31
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ass_tests"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
12
+
13
+ # require "irb"
14
+ # IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,81 @@
1
+ require 'test_helper'
2
+ require 'ass_tests/info_bases'
3
+
4
+ AssTests::InfoBases.describe do
5
+ file :empty_ib do
6
+ # DescribeOptions
7
+ template nil # Путь к шаблону ИБ
8
+ fixtures nil # Объект реализующий интрфейс AssTests::FixturesInterface для
9
+ # заполнения ИБ
10
+ maker nil # Объект реализующий интерфейс AssTests::IbMakerInterface создающий
11
+ # ИБ
12
+ destroyer nil # Объект реализующий интерфейс AssTests::IbDistroyerInterface
13
+ # уничтожающий ИБ
14
+ platform_require ENV['ASS_PLATFORM']
15
+ before_make ->(ib) { puts "Before make #{ib.name}"}
16
+ after_make ->(ib) { puts "After make #{ib.name}"}
17
+ before_rm ->(ib) { puts "Before rm #{ib.name}"}
18
+ after_rm ->(ib) { puts "After rm #{ib.name}"}
19
+ # CommonDescriber
20
+ locale nil
21
+ user 'name'
22
+ password 'password'
23
+ # FileIb
24
+ directory File.expand_path('../../tmp', __FILE__)
25
+ end
26
+
27
+ server :empty_server_ib do
28
+ # DescribeOptions
29
+ template nil
30
+ fixtures nil
31
+ maker nil
32
+ destroyer nil
33
+ platform_require '~> 8.3.8'
34
+ before_make nil
35
+ after_make nil
36
+ before_rm nil
37
+ after_rm nil
38
+ # CommonDescriber
39
+ locale nil
40
+ user 'name'
41
+ password 'password'
42
+ # ServerIb
43
+ agent ENV['ASS_SERVER_AGENT'] # --host 'host:port' --user 'admin' --password 'password'
44
+ claster ENV['ASS_CLASTER'] # --host 'host:port' --user 'admin' --password 'password'
45
+ db ENV['EMPTY_DATA_BASE'] # --host 'host:port' --dbms 'MSSQLServer' --db-name 'db_name' --user 'admin' --password 'password' --create-db
46
+ #db "--host 'host:port' --dbms 'MSSQLServer' --db-name 'db_name' --user 'admin' --password 'password' --create-db"
47
+ schjobdn # Запрет заданий см строка соединения
48
+ end
49
+
50
+ external :acc30, AssTestsTest::Tmp::EXTERNAL_IB_CS do
51
+ platform_require '>= 8.3'
52
+ end
53
+ end
54
+
55
+ module ExampleTest
56
+ describe 'smoky test' do
57
+ it 'empty_ib exists' do
58
+ AssTests::InfoBases[:empty_ib].must_be_instance_of\
59
+ AssTests::InfoBases::InfoBase
60
+ AssTests::InfoBases[:empty_ib].is?(:file).must_equal true
61
+ AssTests::InfoBases[:empty_ib].read_only?.must_equal false
62
+ end
63
+
64
+ it 'empty_server_ib exists' do
65
+ proc {
66
+ AssTests::InfoBases[:empty_server_ib].must_be_instance_of\
67
+ AssTests::InfoBases::InfoBase
68
+ AssTests::InfoBases[:empty_server_ib].is?(:server).must_equal true
69
+ AssTests::InfoBases[:empty_server_ib].read_only?.must_equal false
70
+ }.must_raise NotImplementedError
71
+ end
72
+
73
+ it 'acc30 exists' do
74
+ AssTests::InfoBases[:acc30].must_be_instance_of\
75
+ AssTests::InfoBases::InfoBase
76
+ AssTests::InfoBases[:acc30].is?(:file).must_equal true
77
+ AssTests::InfoBases[:acc30].read_only?.must_equal true
78
+ AssTests::InfoBases[:acc30].platform_require.must_equal '>= 8.3'
79
+ end
80
+ end
81
+ end
data/lib/ass_tests.rb ADDED
@@ -0,0 +1,16 @@
1
+ module AssTests
2
+ class ConfigureError < StandardError; end
3
+ require 'ass_tests/version'
4
+ require 'ass_tests/config'
5
+ require 'ass_tests/fixt'
6
+ require 'ass_tests/externals'
7
+ require 'ass_tests/info_bases'
8
+ end
9
+
10
+ class WIN32OLERuntimeError
11
+ old_message = instance_method(:message)
12
+ define_method(:message) do
13
+ old_message.bind(self).call.force_encoding('ASCII-8BIT')\
14
+ .split('HRESULT')[0].force_encoding('UTF-8').strip
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module AssTests
2
+ module AssDummy
3
+ def ass_dummy(obj)
4
+ eval("#{obj}").new
5
+ end
6
+ class Query
7
+ attr_accessor :МенеджерВременныхТаблиц, :TempTablesManager,
8
+ :Параметры, :Parameters,
9
+ :Текст, :Text
10
+ attr_reader :Выполнить, :Execute,
11
+ :ВыполнитьПакет, :ExecuteBatch,
12
+ :ВыполнитьПакетСПромежуточнымиДанными, :ExecuteBatchWithIntermediateData,
13
+ :НайтиПараметры, :FindParameters,
14
+ :УстановитьПараметр, :SetParameter
15
+ end
16
+
17
+ class QueryResult
18
+ attr_reader :Колонки, :Columns,
19
+ :Выбрать, :Select,
20
+ :Выгрузить, :Unload,
21
+ :Пустой, :IsEmpty
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,47 @@
1
+ module AssTests
2
+ require 'ass_launcher'
3
+ require 'tmpdir'
4
+ TEST_INFOBASE_DIRECTORY = Dir.tmpdir
5
+ ASS_PLATFORM_REQUIRE = ENV['ASS_PLATFORM_REQUIRE'] || '> 0'
6
+ TEST_INFOBASE_DB = ENV['TEST_INFOBASE_DB'] ||\
7
+ '--dbms MSSQLServer --host 127.0.0.1,1433 --user USR1CV8'
8
+ TEST_INFOBASE_CLASTER = ENV['TEST_INFOBASE_CLASTER'] ||\
9
+ '--host 127.0.0.1:1541'
10
+ TEST_INFOBASE_SERVER_AGENT = ENV['TEST_INFOBASE_SERVER_AGENT'] ||\
11
+ '--host 127.0.0.1:1540'
12
+
13
+ def self.configure
14
+ yield config
15
+ end
16
+
17
+ def self.config
18
+ @config ||= Config.new
19
+ end
20
+
21
+ class Config
22
+ attr_writer :platform_require
23
+ def platform_require
24
+ @platform_require ||= ASS_PLATFORM_REQUIRE
25
+ end
26
+
27
+ attr_writer :test_infobase_directory
28
+ def test_infobase_directory
29
+ @test_infobase_directory ||= TEST_INFOBASE_DIRECTORY
30
+ end
31
+
32
+ attr_writer :test_infobase_db
33
+ def test_infobase_db
34
+ @test_infobase_db ||= TEST_INFOBASE_DB
35
+ end
36
+
37
+ attr_writer :test_infobase_claster
38
+ def test_infobase_claster
39
+ @test_infobase_claster ||= TEST_INFOBASE_CLASTER
40
+ end
41
+
42
+ attr_writer :test_infobase_server_agent
43
+ def test_infobase_server_agent
44
+ @test_infobase_server_agent ||= TEST_INFOBASE_SERVER_AGENT
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,135 @@
1
+ module AssTests
2
+ module Support
3
+ def underscore(camel_cased_word)
4
+ return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
5
+ word = camel_cased_word.to_s.gsub(/::/, '/')
6
+ # word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" }
7
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
8
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
9
+ word.tr!("-", "_")
10
+ word.downcase!
11
+ word
12
+ end
13
+
14
+ extend self
15
+ end
16
+ # Externals 1C dataprocessor and report
17
+ module Externals
18
+ require 'ass_launcher'
19
+ class Processor
20
+ attr_reader :path, :root
21
+ def initialize(path, root)
22
+ @path = AssLauncher::Support::Platforms.path(path.to_s).realpath
23
+ @root = AssLauncher::Support::Platforms.path(root)
24
+ end
25
+
26
+ def exist?
27
+ path.exist?
28
+ end
29
+
30
+ def manager
31
+ :ExternalDataProcessors
32
+ end
33
+
34
+ def self.file_ext
35
+ '.epf'
36
+ end
37
+
38
+ def file_ext
39
+ self.class.file_ext
40
+ end
41
+
42
+ # It work only for :thick, :external
43
+ def create(ole_connector, safe_mode = false)
44
+ ole_connector.send(manager).create(connect(ole_connector, safe_mode))
45
+ end
46
+
47
+ def connect(ole_connector, safe_mode = false)
48
+ fail "External not exist `#{path}'" unless exist?
49
+ dd = ole_connector.newObject('BinaryData', path.win_string)
50
+ link = ole_connector.PutToTempStorage(dd)
51
+ ole_connector.send(manager).connect(link, name_for_ass, safe_mode)
52
+ end
53
+
54
+ def connected?(ole_connector)
55
+ begin
56
+ ole_connector.send(manager).create(name_for_ass)
57
+ rescue WIN32OLERuntimeError
58
+ return false
59
+ end
60
+ return true
61
+ end
62
+
63
+ # It work only :thick
64
+ # @todo implemets form opts
65
+ def get_form(ole_connector, name, safe_mode = false, **opts)
66
+ #ole_connector.send(manager).getForm(path.win_string, name.to_s)
67
+ # create(ole_connector).getForm(name.to_s)
68
+ ole_connector.getForm(form_full_name(connect(ole_connector, safe_mode),
69
+ name))
70
+ end
71
+
72
+ def form_full_name(external_name, form_name)
73
+ "#{manager.to_s.gsub(/s\z/,'')}.#{external_name}.Form.#{form_name}"
74
+ end
75
+
76
+ def name
77
+ path.relative_path_from(root).to_s
78
+ end
79
+
80
+ def name_for_ass
81
+ name.gsub('.','_').gsub(/(\/\\)/,'_')
82
+ end
83
+ end
84
+
85
+ class Report < Processor
86
+ def manager
87
+ :ExternalReports
88
+ end
89
+
90
+ def self.file_ext
91
+ '.erf'
92
+ end
93
+ end
94
+
95
+ def self.root=(path)
96
+ @root = path
97
+ end
98
+
99
+ def self.root
100
+ fail 'Specify AssTests::Externals.root= path'\
101
+ unless @root
102
+ @root
103
+ end
104
+
105
+ def self.externals
106
+ r = {}
107
+ Dir.glob(File.join(root,'**/*.{epf,erf}')) do |f|
108
+ ext = new(f)
109
+ r[ext.name] = ext
110
+ end
111
+ r
112
+ end
113
+
114
+ def self.get(name)
115
+ externals[name] || fail(ArgumentError, "Uncknown external `#{name}'")
116
+ end
117
+
118
+ def self.new(path)
119
+ klass(path).new(path, root)
120
+ end
121
+
122
+ KLASES = {'.epf' => Processor,
123
+ '.erf' => Report
124
+ }
125
+
126
+ def self.klass(path)
127
+ KLASES[File.extname(path).downcase] ||\
128
+ fail(ArgumentError, "Uncknown external `#{path}'")
129
+ end
130
+
131
+ def external
132
+ @external ||= AssTests::Externals.get(external_name)
133
+ end
134
+ end
135
+ end