Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: glideapps/quicktype
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f27d5e096ad0c592d6b7aa50c4c56b310356754e
Choose a base ref
...
head repository: glideapps/quicktype
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e6d9552bcb36d29258d8750515d2a0af310aefcd
Choose a head ref
  • 1 commit
  • 8 files changed
  • 1 contributor

Commits on Jan 7, 2023

  1. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    marsam Mario Rodas
    Copy the full SHA
    e6d9552 View commit details
4 changes: 2 additions & 2 deletions .github/workflows/test-pr.yaml
Original file line number Diff line number Diff line change
@@ -36,12 +36,12 @@ jobs:
- dart,schema-dart
- swift,schema-swift
- javascript-prop-types
- ruby

# Partially working
# - schema-typescript # TODO Unify with typescript once fixed

# Implementation is too outdated to test in GitHub Actions
# - ruby,schema-ruby
# - elm,schema-elm

# Language is too niche / obscure to test easily on ubuntu-latest
@@ -96,7 +96,7 @@ jobs:
uses: ruby/setup-ruby@v1
if: ${{ contains(matrix.fixture, 'ruby') }}
with:
ruby-version: "3.0"
ruby-version: "3.2.0"

- name: Setup .NET Core SDK
if: ${{ contains(matrix.fixture, 'csharp') }}
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
"elm-stuff": true,
"dist": true
},
"explorer.excludeGitIgnore": false,
"spellright.documentTypes": [],
"java.configuration.updateBuildConfiguration": "automatic"
}
30 changes: 17 additions & 13 deletions src/quicktype-core/language/ruby/index.ts
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@ import { Option, BooleanOption, EnumOption, OptionValues, getOptionValues } from

import * as keywords from "./keywords";

const forbiddenForObjectProperties = Array.from(new Set([...keywords.keywords, ...keywords.reservedProperties]));

import { Type, EnumType, ClassType, UnionType, ArrayType, MapType, ClassProperty } from "../../Type";
import { matchType, nullableFromUnion, removeNullFromUnion } from "../../TypeUtils";

@@ -22,7 +24,8 @@ import {
isPrintable,
escapeNonPrintableMapper,
intToHex,
snakeCase
snakeCase,
isLetterOrUnderscore
} from "../../support/Strings";
import { RenderContext } from "../../Renderer";

@@ -69,9 +72,7 @@ export class RubyTargetLanguage extends TargetLanguage {
}
}

function isStartCharacter(utf16Unit: number): boolean {
return unicode.isAlphabetic(utf16Unit) || utf16Unit === 0x5f; // underscore
}
const isStartCharacter = isLetterOrUnderscore;

function isPartCharacter(utf16Unit: number): boolean {
const category: string = unicode.getCategory(utf16Unit);
@@ -81,6 +82,9 @@ function isPartCharacter(utf16Unit: number): boolean {
const legalizeName = legalizeCharacters(isPartCharacter);

function simpleNameStyle(original: string, uppercase: boolean): string {
if (/^[0-9]+$/.test(original)) {
original = original + "N";
}
const words = splitIntoWords(original);
return combineWords(
words,
@@ -130,11 +134,11 @@ export class RubyRenderer extends ConvenienceRenderer {
}

protected forbiddenNamesForGlobalNamespace(): string[] {
return keywords.globals.concat(["Types", "JSON", "Dry", "Constructor"]);
return keywords.globals.concat(["Types", "JSON", "Dry", "Constructor", "Self"]);
}

protected forbiddenForObjectProperties(_c: ClassType, _classNamed: Name): ForbiddenWordsInfo {
return { names: keywords.reservedProperties, includeGlobalForbidden: true };
return { names: forbiddenForObjectProperties, includeGlobalForbidden: true };
}

protected makeNamedTypeNamer(): Namer {
@@ -160,7 +164,7 @@ export class RubyRenderer extends ConvenienceRenderer {
_anyType => ["Types::Any", optional],
_nullType => ["Types::Nil", optional],
_boolType => ["Types::Bool", optional],
_integerType => ["Types::Int", optional],
_integerType => ["Types::Integer", optional],
_doubleType => ["Types::Double", optional],
_stringType => ["Types::String", optional],
arrayType => ["Types.Array(", this.dryType(arrayType.items), ")", optional],
@@ -457,7 +461,7 @@ export class RubyRenderer extends ConvenienceRenderer {
this.indent(() => {
const inits: Sourcelike[][] = [];
this.forEachClassProperty(c, "none", (name, jsonName, p) => {
const expression = this.toDynamic(p.type, ["@", name], p.isOptional);
const expression = this.toDynamic(p.type, name, p.isOptional);
inits.push([[`"${stringEscape(jsonName)}"`], [" => ", expression, ","]]);
});
this.emitTable(inits);
@@ -531,9 +535,9 @@ export class RubyRenderer extends ConvenienceRenderer {
this.emitBlock("def to_dynamic", () => {
let first = true;
this.forEachUnionMember(u, nonNulls, "none", null, (name, t) => {
this.emitLine(first ? "if" : "elsif", " @", name, " != nil");
this.emitLine(first ? "if" : "elsif", " ", name, " != nil");
this.indent(() => {
this.emitLine(this.toDynamic(t, ["@", name]));
this.emitLine(this.toDynamic(t, name));
});
first = false;
});
@@ -555,7 +559,7 @@ export class RubyRenderer extends ConvenienceRenderer {

private emitTypesModule() {
this.emitBlock(["module Types"], () => {
this.emitLine("include Dry::Types.module");
this.emitLine("include Dry.Types(default: :nominal)");

const declarations: Sourcelike[][] = [];

@@ -571,7 +575,7 @@ export class RubyRenderer extends ConvenienceRenderer {
double: has.double || t.kind === "double"
};
});
if (has.int) declarations.push([["Int"], [` = ${this._options.strictness}Int`]]);
if (has.int) declarations.push([["Integer"], [` = ${this._options.strictness}Integer`]]);
if (this._options.strictness === Strictness.Strict) {
if (has.nil) declarations.push([["Nil"], [` = ${this._options.strictness}Nil`]]);
}
@@ -581,7 +585,7 @@ export class RubyRenderer extends ConvenienceRenderer {
if (has.double)
declarations.push([
["Double"],
[` = ${this._options.strictness}Float | ${this._options.strictness}Int`]
[` = ${this._options.strictness}Float | ${this._options.strictness}Integer`]
]);
}

7 changes: 7 additions & 0 deletions src/quicktype-core/language/ruby/keywords.ts
Original file line number Diff line number Diff line change
@@ -223,6 +223,7 @@ const kernel = [
"module_eval",
"module_exec",
"name",
"new",
"nil?",
"object_id",
"open",
@@ -293,7 +294,9 @@ export const globals = kernel.concat(globalClasses);
export const reservedProperties = [
"__id__",
"__send__",
"break",
"call",
"case",
"class",
"clone",
"constrained_type",
@@ -321,6 +324,7 @@ export const reservedProperties = [
"meta",
"method",
"methods",
"next",
"object_id",
"optional",
"options",
@@ -333,6 +337,7 @@ export const reservedProperties = [
"remove_instance_variable",
"rule",
"safe",
"self",
"send",
"singleton_class",
"singleton_method",
@@ -347,6 +352,8 @@ export const reservedProperties = [
"try",
"type",
"untaint",
"undef",
"untrust",
"while",
"with"
];
7 changes: 0 additions & 7 deletions test/fixtures.ts
Original file line number Diff line number Diff line change
@@ -245,13 +245,6 @@ abstract class LanguageFixture extends Fixture {
shell.cp(path.join(cwd, this.language.output), outputDir);
}

// If we didn't generate files, don't clean up.
// This happens if something went wrong, so it's good to preserve
// the directory
if (numFiles !== -1) {
shell.rm("-rf", cwd);
}

this.runMessageEnd(message, numFiles);
}
}
2 changes: 0 additions & 2 deletions test/fixtures/ruby/.bundle/config

This file was deleted.

44 changes: 19 additions & 25 deletions test/fixtures/ruby/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,41 +1,35 @@
GEM
remote: https://rubygems.org/
specs:
concurrent-ruby (1.0.5)
dry-configurable (0.7.0)
concurrent-ruby (1.1.10)
dry-core (1.0.0)
concurrent-ruby (~> 1.0)
dry-container (0.6.0)
zeitwerk (~> 2.6)
dry-inflector (1.0.0)
dry-logic (1.5.0)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1, >= 0.1.3)
dry-core (0.4.4)
concurrent-ruby (~> 1.0)
dry-equalizer (0.2.0)
dry-logic (0.4.2)
dry-container (~> 0.2, >= 0.2.6)
dry-core (~> 0.2)
dry-equalizer (~> 0.2)
dry-struct (0.4.0)
dry-core (~> 0.4, >= 0.4.1)
dry-equalizer (~> 0.2)
dry-types (~> 0.12, >= 0.12.2)
dry-core (~> 1.0, < 2)
zeitwerk (~> 2.6)
dry-struct (1.6.0)
dry-core (~> 1.0, < 2)
dry-types (>= 1.7, < 2)
ice_nine (~> 0.11)
dry-types (0.12.2)
zeitwerk (~> 2.6)
dry-types (1.7.0)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1)
dry-container (~> 0.3)
dry-core (~> 0.2, >= 0.2.1)
dry-equalizer (~> 0.2)
dry-logic (~> 0.4, >= 0.4.2)
inflecto (~> 0.0.0, >= 0.0.2)
dry-core (~> 1.0, < 2)
dry-inflector (~> 1.0, < 2)
dry-logic (>= 1.4, < 2)
zeitwerk (~> 2.6)
ice_nine (0.11.2)
inflecto (0.0.2)
zeitwerk (2.6.6)

PLATFORMS
ruby
arm64-darwin-22

DEPENDENCIES
dry-struct
dry-types

BUNDLED WITH
1.16.1
2.4.2
20 changes: 18 additions & 2 deletions test/languages.ts
Original file line number Diff line number Diff line change
@@ -266,7 +266,7 @@ export const CrystalLanguage: Language = {
export const RubyLanguage: Language = {
name: "ruby",
base: "test/fixtures/ruby",
setupCommand: "bundle install --path vendor/bundle",
setupCommand: "bundle install",
compileCommand: "true",
runCommand(sample: string) {
return `bundle exec main.rb "${sample}"`;
@@ -328,7 +328,23 @@ export const RubyLanguage: Language = {
features: ["enum", "union", "no-defaults"],
output: "TopLevel.rb",
topLevel: "TopLevel",
skipJSON: [],
skipJSON: [
// Chokes on { "1": "one" } because _[0-9]+ is reserved in ruby
"blns-object.json",
// Ruby union code does not work with new Dry
// can't convert Symbol into Hash (Dry::Types::CoercionError)
"bug863.json",
"combinations1.json",
"combinations2.json",
"combinations3.json",
"combinations4.json",
"nst-test-suite.json",
"optional-union.json",
"union-constructor-clash.json",
"unions.json",
"nbl-stats.json",
"kitchen-sink.json"
],
skipSchema: [
// We don't generate a convenience method for top-level enums
"top-level-enum.schema"