spec_forge 0.3.0 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f04f0ef7fc98b027990b272a524856731de03b46f9898430f6ccfa30bc2f3fe7
4
- data.tar.gz: a0130baec24c851c981aa76a4af01011e0944ece84965da37b9ad8630cc3dca3
3
+ metadata.gz: d8f32cf2a6adb2037851cc3408d7bcc093b3c28d061dbc0a00abcdd2de4d3b49
4
+ data.tar.gz: d5aff61ab4b2b593c3412cb04e54ec4cd0af1160571105c15c7d80f980267fe9
5
5
  SHA512:
6
- metadata.gz: 0b933a4b603f899c5140997c0e551d86c497671ed2447088489bb3f5dbdb056bb89757bc67bd4fc72033ddede7c54df64e9eb73b64d76092c6d5dbf997c31ab9
7
- data.tar.gz: 8b274025784f417bd7250f0fd716414c5511d392af4e2daabe1eb8fe1116f9416415f2b1d4c0495922fd7509b4a3b5fb648a86a4a62a6ced69b5392da906140b
6
+ metadata.gz: 8f2fe0cb87f66820f2a4273e137052eade6d34d2c01594a44d7a7d56e61d6896a41a476a8730f5bdd744efffea20c5b1afb00471d43b10cae548ab0775e8e936
7
+ data.tar.gz: 3ec74966a47dcf22bc16ae5e64391ede4963a32e22a62f6a2f1189f6e881747b33f74326b190dbd9580ec2ebb0f402844e8d00e3e8986c2ba5c9aae796520a74
data/CHANGELOG.md CHANGED
@@ -13,6 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
 
14
14
  ### Removed
15
15
 
16
+ ## [0.3.2] - 12025-02-20
17
+
18
+ ### Changed
19
+
20
+ - Moved Regex into its own Attribute class
21
+ - Fixed Regex parsing
22
+
16
23
  ## [0.3.0] - 12025-02-17
17
24
 
18
25
  ### Added
@@ -64,7 +71,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
64
71
 
65
72
  - Initial commit
66
73
 
67
- [unreleased]: https://github.com/itsthedevman/spec_forge/compare/v0.3.0...HEAD
74
+ [unreleased]: https://github.com/itsthedevman/spec_forge/compare/v0.3.2...HEAD
75
+ [0.3.2]: https://github.com/itsthedevman/spec_forge/compare/v0.3.0...v0.3.2
68
76
  [0.3.0]: https://github.com/itsthedevman/spec_forge/compare/v0.2.0...v0.3.0
69
77
  [0.2.0]: https://github.com/itsthedevman/spec_forge/compare/v0.1.0...v0.2.0
70
78
  [0.1.0]: https://github.com/itsthedevman/spec_forge/compare/a8a991c25dcbd472a5fd975e96aa223b05948618...v0.1.0
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # SpecForge
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/spec_forge.svg)](https://badge.fury.io/rb/spec_forge)
4
+ ![Ruby Version](https://img.shields.io/badge/ruby-3.3.7-ruby)
4
5
  [![Tests](https://github.com/itsthedevman/spec_forge/actions/workflows/main.yml/badge.svg)](https://github.com/itsthedevman/spec_forge/actions/workflows/main.yml)
5
- ![Ruby Version](https://img.shields.io/badge/ruby-3.3.6-ruby)
6
6
 
7
7
  Write API tests in YAML that read like documentation:
8
8
 
@@ -12,9 +12,9 @@ user_profile:
12
12
  expectations:
13
13
  - expect:
14
14
  status: 200
15
- json:
16
- name: kind_of.string
17
- email: /@/
15
+ json:
16
+ name: kind_of.string
17
+ email: /@/
18
18
  ```
19
19
 
20
20
  That's a complete test. No Ruby code, no configuration files, no HTTP client setup - just a clear description of what you're testing. Under the hood, you get all the power of RSpec's matchers, Faker's data generation, and FactoryBot's test objects.
@@ -52,9 +52,14 @@ Current development priorities:
52
52
 
53
53
  Have a feature request? Open an issue on GitHub!
54
54
 
55
+ ## Looking for a Software Engineer?
56
+
57
+ I'm currently looking for opportunities where I can tackle meaningful problems and help build reliable software while mentoring the next generation of developers. If you're looking for a senior engineer with full-stack Rails expertise and a passion for clean, maintainable code, let's talk!
58
+
59
+ [bryan@itsthedevman.com](mailto:bryan@itsthedevman.com)
60
+
55
61
  ## Table of Contents
56
62
 
57
- - [Features](#features)
58
63
  - [Compatibility](#compatibility)
59
64
  - [Installation](#installation)
60
65
  - [Getting Started](#getting-started)
@@ -88,12 +93,14 @@ Have a feature request? Open an issue on GitHub!
88
93
  - [How Tests Work](#how-tests-work)
89
94
  - [Contributing](#contributing)
90
95
  - [License](#license)
91
- - [Looking for a Software Engineer?](#looking-for-a-software-engineer)
96
+ - [Credits](#credits)
97
+
98
+ Also see: [API Documentation](https://itsthedevman.com/docs/spec_forge)
92
99
 
93
100
  ## Compatibility
94
101
 
95
102
  Currently tested on:
96
- - MRI Ruby 3.0+
103
+ - MRI Ruby 3.2+
97
104
  - NixOS (see `flake.nix` for details)
98
105
 
99
106
  ## Installation
@@ -393,13 +400,13 @@ list_posts:
393
400
  expectations:
394
401
  - expect:
395
402
  status: 200
396
- json:
397
- posts:
398
- matcher.include:
399
- - author:
400
- id: variables.author.id
401
- name: variables.author.name
402
- category: variables.category_name
403
+ json:
404
+ posts:
405
+ matcher.include:
406
+ - author:
407
+ id: variables.author.id
408
+ name: variables.author.name
409
+ category: variables.category_name
403
410
  ```
404
411
 
405
412
  ### Transformations
@@ -644,6 +651,10 @@ Please note that this project is released with a [Contributor Code of Conduct](C
644
651
 
645
652
  The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
646
653
 
647
- ## Looking for a Software Engineer?
654
+ ## Changelog
655
+
656
+ See [CHANGELOG.md](CHANGELOG.md) for a list of changes.
657
+
658
+ ## Credits
648
659
 
649
- I'm looking for work! Please send serious enquiries to bryan@itsthedevman.com
660
+ - Author: Bryan "itsthedevman"
@@ -3,8 +3,6 @@
3
3
  module SpecForge
4
4
  class Attribute
5
5
  class Literal < Attribute
6
- REGEX_REGEX = /^\/.+\/[mnix\s]*$/i
7
-
8
6
  attr_reader :value
9
7
 
10
8
  #
@@ -14,18 +12,10 @@ module SpecForge
14
12
  def initialize(input)
15
13
  super
16
14
 
17
- @value =
18
- case input
19
- when REGEX_REGEX
20
- Regexp.new(input)
21
- else
22
- input
23
- end
15
+ @value = input
24
16
  end
25
17
 
26
- def resolve
27
- @value
28
- end
18
+ alias_method :resolve, :value
29
19
  end
30
20
  end
31
21
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SpecForge
4
+ class Attribute
5
+ class Regex < Attribute
6
+ KEYWORD_REGEX = /^\/(?<content>[\s\S]+)\/(?<flags>[mnix\s]*)$/i
7
+
8
+ attr_reader :value
9
+
10
+ def initialize(input)
11
+ super
12
+
13
+ @value = parse_regex(input)
14
+ end
15
+
16
+ def resolve
17
+ @value
18
+ end
19
+
20
+ private
21
+
22
+ def parse_regex(input)
23
+ match = input.match(KEYWORD_REGEX)
24
+ captures = match.named_captures.symbolize_keys
25
+
26
+ flags = parse_flags(captures[:flags])
27
+ Regexp.new(captures[:content], flags)
28
+ end
29
+
30
+ # I would've used Regexp.new(string, string), but it raises when "n" is provided as a flag
31
+ def parse_flags(flags)
32
+ return 0 if flags.blank?
33
+
34
+ flags.strip.chars.reduce(0) do |options, flag|
35
+ case flag
36
+ when "i"
37
+ options | Regexp::IGNORECASE
38
+ when "m"
39
+ options | Regexp::MULTILINE
40
+ when "x"
41
+ options | Regexp::EXTENDED
42
+ when "n"
43
+ options | Regexp::NOENCODING
44
+ else
45
+ raise ArgumentError, "unknown regexp option: #{flag}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -10,6 +10,7 @@ require_relative "attribute/factory"
10
10
  require_relative "attribute/faker"
11
11
  require_relative "attribute/literal"
12
12
  require_relative "attribute/matcher"
13
+ require_relative "attribute/regex"
13
14
  require_relative "attribute/resolvable_array"
14
15
  require_relative "attribute/resolvable_hash"
15
16
  require_relative "attribute/transform"
@@ -81,6 +82,8 @@ module SpecForge
81
82
  Matcher.new(string)
82
83
  when Factory::KEYWORD_REGEX
83
84
  Factory.new(string)
85
+ when Regex::KEYWORD_REGEX
86
+ Regex.new(string)
84
87
  else
85
88
  Literal.new(string)
86
89
  end
@@ -26,8 +26,11 @@ module SpecForge
26
26
  def normalize_hash(hash)
27
27
  hash =
28
28
  hash.transform_values do |attribute|
29
- if attribute.is_a?(Attribute::Literal)
30
- normalize_literal(attribute.value)
29
+ case attribute
30
+ when Attribute::Regex
31
+ Attribute.from("matcher.match" => attribute.resolve)
32
+ when Attribute::Literal
33
+ Attribute.from("matcher.eq" => attribute.resolve)
31
34
  else
32
35
  attribute
33
36
  end
@@ -35,14 +38,6 @@ module SpecForge
35
38
 
36
39
  Attribute.from(hash)
37
40
  end
38
-
39
- def normalize_literal(value)
40
- if value.is_a?(Regexp)
41
- Attribute.from("matcher.match" => value)
42
- else
43
- Attribute.from("matcher.eq" => value)
44
- end
45
- end
46
41
  end
47
42
  end
48
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SpecForge
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spec_forge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-17 00:00:00.000000000 Z
11
+ date: 2025-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -166,6 +166,7 @@ files:
166
166
  - lib/spec_forge/attribute/literal.rb
167
167
  - lib/spec_forge/attribute/matcher.rb
168
168
  - lib/spec_forge/attribute/parameterized.rb
169
+ - lib/spec_forge/attribute/regex.rb
169
170
  - lib/spec_forge/attribute/resolvable.rb
170
171
  - lib/spec_forge/attribute/resolvable_array.rb
171
172
  - lib/spec_forge/attribute/resolvable_hash.rb