faccts 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4ab5b68cc81737ad2a9de3e64778e6a17f3174e70ef2b361c1deeb8749c6d4ae
4
+ data.tar.gz: 2b9568a2176536a7f4121304d8009ba76590f105ca12e7f99eef6c5d12d81fcb
5
+ SHA512:
6
+ metadata.gz: 664e60d3cd0143b32705fbe1851dd9a5bc8a45b6662cd4b14bc36720e675390cbc1a066d01e61c0032ed456d28567daf4f1faec3c6ca7f94089bcfe76b28ce61
7
+ data.tar.gz: 813a429fd451bcaeb540dd2daf36c07a559ba3dc006fc6832be919bfc583497bf5dc9d5561f0c940221b947b183523071147e4998055f4f6a55f7856459be195
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/exe/faccts ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift("#{__dir__}/../lib")
5
+ require "faccts"
6
+
7
+ Faccts::BasicAcceptanceTester.new.run!
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class YAMLFileReader
5
+ TARGET_FILE_PATH = "./acceptance_tests.yaml"
6
+
7
+ def read_file!
8
+ raise FileNotFoundError unless file_exists?
9
+
10
+ target_file_contents
11
+ end
12
+
13
+ class FileNotFoundError < ::StandardError
14
+ ERROR_MESSAGE = "Cannot find acceptance test specification file '#{TARGET_FILE_PATH}'".freeze
15
+
16
+ def initialize(_msg = "")
17
+ super(ERROR_MESSAGE)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def file_exists?
24
+ File.exist?(TARGET_FILE_PATH)
25
+ end
26
+
27
+ def target_file_contents
28
+ File.read(TARGET_FILE_PATH)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class YAMLTestParser
5
+ class YAMLTestAssertionParser
6
+ class AssertionSpecificationParser
7
+ def parse(assertion_name_specification)
8
+ assertion, remaining_specification = extract_assertion_up_to_first_argument(assertion_name_specification)
9
+
10
+ return assertion if remaining_specification.nil?
11
+
12
+ assertion.combined_with(parse(remaining_specification))
13
+ end
14
+
15
+ def extract_assertion_up_to_first_argument(assert_specification)
16
+ @specification = assert_specification
17
+
18
+ return no_argument_assertion unless specification_contains_argument?
19
+
20
+ [extracted_assertion_up_to_first_argument, unextracted_specification]
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :specification
26
+
27
+ def no_argument_assertion
28
+ assertion = Faccts::TestAssertion.new
29
+
30
+ assertion.action_name = specification
31
+ assertion.arguments = []
32
+
33
+ assertion
34
+ end
35
+
36
+ def specification_contains_argument?
37
+ spec_contains_an_open_and_close_wrapper_character?
38
+ end
39
+
40
+ def spec_contains_an_open_and_close_wrapper_character?
41
+ specification.length > 1 && specification.count(ARGUMENT_WRAPPER_CHAR) > 1
42
+ end
43
+
44
+ def extracted_assertion_up_to_first_argument
45
+ assertion = Faccts::TestAssertion.new
46
+
47
+ assertion.action_name = specification_before_open_wrapper_char + ARGUMENT_NAME_PLACEHOLDER
48
+ assertion.arguments = [value_between_open_and_close_wrapper_chars]
49
+
50
+ assertion
51
+ end
52
+
53
+ def specification_before_open_wrapper_char
54
+ specification[...open_wrapper_index]
55
+ end
56
+
57
+ def open_wrapper_index
58
+ specification.index(ARGUMENT_WRAPPER_CHAR)
59
+ end
60
+
61
+ def value_between_open_and_close_wrapper_chars
62
+ specification[index_after_open_wrapper...close_wrapper_index]
63
+ end
64
+
65
+ def index_after_open_wrapper
66
+ open_wrapper_index + 1
67
+ end
68
+
69
+ def close_wrapper_index
70
+ specification_after_open_wrapper = specification[index_after_open_wrapper..]
71
+
72
+ index_after_open_wrapper \
73
+ + specification_after_open_wrapper.index(ARGUMENT_WRAPPER_CHAR)
74
+ end
75
+
76
+ def unextracted_specification
77
+ specification_after_first_argument
78
+ end
79
+
80
+ def specification_after_first_argument
81
+ index_after_close_wrapper = close_wrapper_index + 1
82
+
83
+ specification[index_after_close_wrapper..]
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class YAMLTestParser
5
+ class YAMLTestAssertionParser
6
+ ARGUMENT_WRAPPER_CHAR = "\""
7
+ ARGUMENT_NAME_PLACEHOLDER = "X"
8
+ ASSERTION_NODE_NAME = "assert"
9
+
10
+ def initialize(assertion_specification_parsing_strategy)
11
+ @assertion_specification_parser = assertion_specification_parsing_strategy
12
+ end
13
+
14
+ def parse(assertion_specification)
15
+ @assertion_specification = assertion_specification
16
+
17
+ generated_assertion = assertion_specification_parser.parse(assertion_name_specification)
18
+ generated_assertion.name = test_name
19
+
20
+ generated_assertion
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :assertion_specification_parser, :assertion_specification
26
+
27
+ def assertion_name_specification
28
+ assertion_specification[test_name][ASSERTION_NODE_NAME]
29
+ end
30
+
31
+ def test_name
32
+ assertion_specification.keys[0]
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Faccts
6
+ class YAMLTestParser
7
+ TEST_SUITE_ROOT_NODE_NAME = "tests"
8
+ ASSERTION_NODE_NAME = "assert"
9
+
10
+ def initialize(test_assertion_parser_strategy)
11
+ @parser = StandardYAMLParser.new
12
+ @test_assertion_extractor = TestAssertionExtractor.new(test_assertion_parser_strategy)
13
+ end
14
+
15
+ def create_tests!(test_specification_yaml)
16
+ @test_specification = parser.parse_tests!(test_specification_yaml)
17
+
18
+ validate_specification!
19
+
20
+ assertions = test_assertions_from_specification
21
+
22
+ raise NoTestsGivenError if assertions.empty?
23
+
24
+ assertions
25
+ rescue ::Psych::Exception => e
26
+ raise InvalidYAMLError, e.message
27
+ end
28
+
29
+ class NoTestsGivenError < ::StandardError
30
+ ERROR_MESSAGE = "Cannot generate acceptance tests - no tests have been specified!"
31
+
32
+ def initialize(assertion_name = "")
33
+ super(ERROR_MESSAGE % assertion_name)
34
+ end
35
+ end
36
+
37
+ class InvalidYAMLError < ::StandardError
38
+ ERROR_MESSAGE = "Cannot parse acceptance tests file"
39
+ ERROR_TEMPLATE = "#{ERROR_MESSAGE} - %s".freeze
40
+
41
+ def initialize(parse_failure_message = "")
42
+ if parse_failure_message == ""
43
+ super(ERROR_MESSAGE)
44
+ else
45
+ super(ERROR_TEMPLATE % parse_failure_message)
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ attr_reader :parser, :test_specification, :test_assertion_extractor
53
+
54
+ def validate_specification!
55
+ raise NoTestsGivenError if test_specification.nil?
56
+ raise NoTestsGivenError if tests.nil?
57
+ raise NoTestsGivenError unless tests.respond_to? :keys
58
+ end
59
+
60
+ def test_assertions_from_specification
61
+ all_test_names
62
+ .map { |test_name| test_assertion_extractor.from_test_name(tests, test_name) }
63
+ .compact
64
+ end
65
+
66
+ def all_test_names
67
+ tests.keys
68
+ end
69
+
70
+ def tests
71
+ test_specification[TEST_SUITE_ROOT_NODE_NAME]
72
+ end
73
+
74
+ class TestAssertionExtractor
75
+ def initialize(test_assertion_parser_strategy)
76
+ @test_assertion_parser = test_assertion_parser_strategy
77
+ end
78
+
79
+ def from_test_name(tests, test_name)
80
+ @tests = tests
81
+ @test_name = test_name
82
+
83
+ return unless test_contains_assertion?
84
+ return if assertion_is_empty?
85
+
86
+ test_assertion_parser.parse(test_node)
87
+ end
88
+
89
+ def test_contains_assertion?
90
+ test_assertion_node.respond_to?(:keys) && test_assertion_node.keys.include?(ASSERTION_NODE_NAME)
91
+ end
92
+
93
+ def test_assertion_node
94
+ tests[test_name]
95
+ end
96
+
97
+ def assertion_is_empty?
98
+ name_from_assertion_node.nil?
99
+ end
100
+
101
+ def test_node
102
+ { test_name => test_assertion_node }
103
+ end
104
+
105
+ def name_from_assertion_node
106
+ tests[test_name][ASSERTION_NODE_NAME]
107
+ end
108
+
109
+ private
110
+
111
+ attr_reader :test_assertion_parser, :tests, :test_name
112
+ end
113
+
114
+ class StandardYAMLParser
115
+ def parse_tests!(test_specification)
116
+ YAML.load(test_specification)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class RustCodeGenerator
5
+ NO_CODE = ""
6
+
7
+ def initialize(test_assertion_generator_strategy, fixed_template_fetcher_strategy)
8
+ @test_assertion_code_generator = test_assertion_generator_strategy
9
+ @fixed_code_template = RustCodeTemplate.new(fixed_template_fetcher_strategy)
10
+ end
11
+
12
+ def generate_from_test_suite!(test_specification_suite)
13
+ @test_specification_suite = test_specification_suite
14
+
15
+ return NO_CODE if test_specification_suite.empty?
16
+
17
+ wrapped_in_fixed_code_template(code_from_test_specification_suite)
18
+ end
19
+
20
+ class RustCodeTemplate
21
+ RUST_TEMPLATE_INSERT_SYMBOL = "/*{}*/"
22
+
23
+ def initialize(fetcher_strategy)
24
+ @code_template_fetcher = fetcher_strategy
25
+ end
26
+
27
+ def generate_with_values(*values)
28
+ values.reduce(code_template) do |template, value|
29
+ insert_value_into_placeholder(template, value)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :code_template_fetcher
36
+
37
+ def code_template
38
+ code_template_fetcher.code_template
39
+ end
40
+
41
+ def insert_value_into_placeholder(template, value)
42
+ template.sub(RUST_TEMPLATE_INSERT_SYMBOL, value)
43
+ end
44
+ end
45
+
46
+ class BasicRustTestAssertionCallTemplateFetcher
47
+ def code_template
48
+ + " name = \"/*{}*/\";\n" \
49
+ + " result = /*{}*/;\n" \
50
+ + " result_output = if result == true { \"PASS\" } else { \"FAIL\" };\n" \
51
+ + " test_result_output = format!(\"{},{}\", name, result_output);\n" \
52
+ + " test_suite_result_output += &test_result_output;\n" \
53
+ + " test_suite_result_output += \"\\n\";\n"
54
+ end
55
+ end
56
+
57
+ class BasicRustMainProgramTemplateFetcher
58
+ def code_template
59
+ "use std::fs;\n" \
60
+ + "mod fixture;\n" \
61
+ + "\n" \
62
+ + "use crate::fixture::*;\n" \
63
+ + "\n" \
64
+ + "fn main() {\n" \
65
+ + " let mut test_suite_result_output = String::from(\"name,result\\n\");\n" \
66
+ + " let mut name: &str;\n" \
67
+ + " let mut result: bool;\n" \
68
+ + " let mut result_output: &str;\n" \
69
+ + " let mut test_result_output: String;\n" \
70
+ + "\n" \
71
+ + "/*{}*/" \
72
+ + "\n" \
73
+ + " let _ = fs::write(\"./results.faccts\", test_suite_result_output);\n" \
74
+ + "}\n"
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ attr_reader :test_assertion_code_generator, :fixed_code_template, :test_specification_suite
81
+
82
+ def wrapped_in_fixed_code_template(value)
83
+ fixed_code_template.generate_with_values(value)
84
+ end
85
+
86
+ def code_from_test_specification_suite
87
+ generated_test_assertion_list.join
88
+ end
89
+
90
+ def generated_test_assertion_list
91
+ test_specification_suite.map do |assert_specification|
92
+ test_assertion_code_generator.generate!(assert_specification)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class RustCodeGenerator
5
+ class RustNameToFunctionCallConverter
6
+ def initialize
7
+ @character_converter = RustCharacterConverter.new
8
+ end
9
+
10
+ def convert!(test_assertion)
11
+ @action_name = test_assertion.action_name
12
+ @arguments = test_assertion.arguments || []
13
+
14
+ converted_name = converted_characters(stripped_action_name)
15
+
16
+ raise InvalidNameError if all_characters_were_removed?(converted_name)
17
+
18
+ "#{converted_name}(#{converted_arguments})"
19
+ end
20
+
21
+ class InvalidNameError < ::StandardError; end
22
+
23
+ private
24
+
25
+ attr_reader :character_converter, :action_name, :arguments
26
+
27
+ def stripped_action_name
28
+ action_name.strip
29
+ end
30
+
31
+ def converted_characters(name)
32
+ name.chars.map { |char| character_converter.convert!(char) }.join
33
+ end
34
+
35
+ def all_characters_were_removed?(converted_name)
36
+ converted_name == ""
37
+ end
38
+
39
+ def converted_arguments
40
+ return "" unless arguments.length.positive?
41
+
42
+ arguments.map { |a| "\"#{a}\"" }.join(", ")
43
+ end
44
+
45
+ class RustCharacterConverter
46
+ WHITESPACE_CHARACTERS = " \n\t"
47
+ ALPHANUMERIC_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
48
+ SUPPORTED_CHARACTERS = "#{ALPHANUMERIC_CHARACTERS}#{WHITESPACE_CHARACTERS}".freeze
49
+
50
+ def convert!(name_character)
51
+ @input_character = name_character
52
+
53
+ return "" unless supported_character?
54
+ return "_" if whitespace?
55
+
56
+ name_character
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :input_character
62
+
63
+ def supported_character?
64
+ SUPPORTED_CHARACTERS.include?(input_character)
65
+ end
66
+
67
+ def whitespace?
68
+ WHITESPACE_CHARACTERS.include?(input_character)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class RustCodeGenerator
5
+ class RustTestAssertionCodeGenerator
6
+ def initialize(function_call_converter_strategy, template_fetcher_strategy)
7
+ @function_call_converter = function_call_converter_strategy
8
+ @code_template = RustCodeTemplate.new(template_fetcher_strategy)
9
+ end
10
+
11
+ def generate!(test_assertion)
12
+ @test_assertion = test_assertion
13
+
14
+ code_template.generate_with_values(*injectable_assertion_values)
15
+ rescue RustNameToFunctionCallConverter::InvalidNameError
16
+ raise UnnameableAssertionError, test_assertion.action_name
17
+ end
18
+
19
+ class UnnameableAssertionError < ::StandardError
20
+ ERROR_TEMPLATE = "Cannot interpret '%s' as a test phase command\n" \
21
+ "Please ensure your test phases include alphanumeric characters!"
22
+
23
+ def initialize(assertion_name = "")
24
+ super(ERROR_TEMPLATE % assertion_name)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def injectable_assertion_values
31
+ [test_assertion.name, test_assertion_as_rust_function].compact
32
+ end
33
+
34
+ def test_assertion_as_rust_function
35
+ function_call_converter.convert!(test_assertion)
36
+ end
37
+
38
+ attr_reader :function_call_converter, :test_assertion, :code_template, :test_assertion_code_generator
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class RustFileWriter
5
+ TARGET_FILE_PATH = "./src/main.rs"
6
+
7
+ def write_file!(code_to_write)
8
+ raise FileAlreadyExistsError if file_already_exists?
9
+
10
+ @file_contents = code_to_write
11
+ write_file
12
+ end
13
+
14
+ class FileAlreadyExistsError < ::StandardError
15
+ ERROR_MESSAGE = "Target generation file '#{TARGET_FILE_PATH}'" \
16
+ + " already exists.\nI don't want to overwrite it!"
17
+
18
+ def initialize(_msg = "")
19
+ super(ERROR_MESSAGE)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :file_contents
26
+
27
+ def write_file
28
+ File.write(TARGET_FILE_PATH, file_contents)
29
+ end
30
+
31
+ def file_already_exists?
32
+ File.exist?(TARGET_FILE_PATH)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class BasicConsoleOutput
5
+ PROCESS_COMPLETED_MESSAGE = "Acceptance tests successfully written!"
6
+
7
+ def run
8
+ yield
9
+ puts PROCESS_COMPLETED_MESSAGE
10
+ rescue StandardError => e
11
+ puts e.message
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class TestAssertion
5
+ attr_accessor :name, :action_name, :arguments
6
+
7
+ def combined_with(other)
8
+ combined_assertion = TestAssertion.new
9
+
10
+ combined_assertion.action_name = action_name + other.action_name
11
+ combined_assertion.arguments = arguments + other.arguments
12
+
13
+ combined_assertion
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class AcceptanceTester
5
+ def run!
6
+ assert_strategies_are_loaded!
7
+
8
+ report_feedback do
9
+ export(
10
+ code_generated_from(
11
+ test_suite_data_parsed_from(
12
+ test_specification
13
+ )
14
+ )
15
+ )
16
+ end
17
+ end
18
+
19
+ class MissingStrategyError < ::StandardError
20
+ ERROR_TEMPLATE = "Could not find %s strategy! Please contact your administrator"
21
+
22
+ def initialize(msg = "")
23
+ super(ERROR_TEMPLATE % msg)
24
+ end
25
+ end
26
+
27
+ class NoTestSpecificationLoadStrategyError < MissingStrategyError
28
+ def initialize
29
+ super("test loading")
30
+ end
31
+ end
32
+
33
+ class NoParsingStrategyError < MissingStrategyError
34
+ def initialize
35
+ super("test parsing")
36
+ end
37
+ end
38
+
39
+ class NoCodeGenerationStrategyError < MissingStrategyError
40
+ def initialize
41
+ super("code generation")
42
+ end
43
+ end
44
+
45
+ class NoTestExportStrategyError < MissingStrategyError
46
+ def initialize
47
+ super("test exporting")
48
+ end
49
+ end
50
+
51
+ class NoFeedbackOutputStrategyError < MissingStrategyError
52
+ def initialize
53
+ super("feedback output")
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def assert_strategies_are_loaded!
60
+ required_strategies_table.each do |action, missing_action_error|
61
+ raise missing_action_error unless respond_to? action
62
+ end
63
+ end
64
+
65
+ def required_strategies_table
66
+ {
67
+ test_specification: NoTestSpecificationLoadStrategyError,
68
+ test_suite_data_parsed_from: NoParsingStrategyError,
69
+ code_generated_from: NoCodeGenerationStrategyError,
70
+ export: NoTestExportStrategyError,
71
+ report_feedback: NoFeedbackOutputStrategyError
72
+ }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ class BasicAcceptanceTester < AcceptanceTester
5
+ def initialize
6
+ @file_reader = YAMLFileReader.new
7
+ @spec_parser = YAMLTestParser.new(
8
+ YAMLTestParser::YAMLTestAssertionParser.new(
9
+ YAMLTestParser::YAMLTestAssertionParser::AssertionSpecificationParser.new
10
+ )
11
+ )
12
+ @code_generator = RustCodeGenerator.new(
13
+ RustCodeGenerator::RustTestAssertionCodeGenerator.new(
14
+ RustCodeGenerator::RustNameToFunctionCallConverter.new,
15
+ RustCodeGenerator::BasicRustTestAssertionCallTemplateFetcher.new
16
+ ),
17
+ RustCodeGenerator::BasicRustMainProgramTemplateFetcher.new
18
+ )
19
+ @file_writer = RustFileWriter.new
20
+ @feedback_reporter = BasicConsoleOutput.new
21
+ end
22
+
23
+ def test_specification
24
+ file_reader.read_file!
25
+ end
26
+
27
+ def test_suite_data_parsed_from(specification)
28
+ spec_parser.create_tests!(specification)
29
+ end
30
+
31
+ def code_generated_from(test_suite)
32
+ code_generator.generate_from_test_suite!(test_suite)
33
+ end
34
+
35
+ def export(test_code)
36
+ file_writer.write_file!(test_code)
37
+ end
38
+
39
+ def report_feedback(&)
40
+ feedback_reporter.run(&)
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :file_reader, :spec_parser, :code_generator, :file_writer, :feedback_reporter
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faccts
4
+ VERSION = "0.1.0"
5
+ end
data/lib/faccts.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "faccts/version"
4
+ require "faccts"
5
+
6
+ module Faccts
7
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: faccts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - bull313
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Execute automated acceptance tests for your project
13
+ executables:
14
+ - faccts
15
+ extensions: []
16
+ extra_rdoc_files: []
17
+ files:
18
+ - Rakefile
19
+ - exe/faccts
20
+ - lib/faccts.rb
21
+ - lib/faccts/01_loading_test_specification/file_reader.rb
22
+ - lib/faccts/02_parsing_test_specification/yaml_assertion_specification_parser.rb
23
+ - lib/faccts/02_parsing_test_specification/yaml_test_assertion_parser.rb
24
+ - lib/faccts/02_parsing_test_specification/yaml_test_parser.rb
25
+ - lib/faccts/03_generating_code/rust_code_generator.rb
26
+ - lib/faccts/03_generating_code/rust_name_to_function_call_converter.rb
27
+ - lib/faccts/03_generating_code/rust_test_assertion_code_generator.rb
28
+ - lib/faccts/04_exporting_results/file_writer.rb
29
+ - lib/faccts/05_reporting_feedback/basic_console_output.rb
30
+ - lib/faccts/entities/test_assertion.rb
31
+ - lib/faccts/integration/acceptance_tester.rb
32
+ - lib/faccts/integration/basic_acceptance_tester.rb
33
+ - lib/faccts/version.rb
34
+ homepage: https://github.com/bull313/faccts
35
+ licenses: []
36
+ metadata:
37
+ rubygems_mfa_required: 'true'
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 3.1.0
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubygems_version: 3.6.9
53
+ specification_version: 4
54
+ summary: FAccTs - Framework for Acceptance Tests
55
+ test_files: []