Bläddra i källkod

Merge branch 'master' into bug/2903-wrong-font-for-error

bubble
shockey 7 år sedan
committed by GitHub
förälder
incheckning
4f1772f654
37 ändrade filer med 580 tillägg och 603 borttagningar
  1. +5
    -0
      README.md
  2. +1
    -0
      dist/index.html
  3. +0
    -1
      make-webpack-config.js
  4. +0
    -1
      package.json
  5. +1
    -1
      src/core/components/info.jsx
  6. +4
    -3
      src/core/components/layout-utils.jsx
  7. +2
    -2
      src/core/components/models.jsx
  8. +3
    -2
      src/core/components/schemes.jsx
  9. +13
    -11
      src/core/json-schema-components.js
  10. +0
    -67
      src/core/path-translator.js
  11. +1
    -1
      src/core/plugins/auth/actions.js
  12. +0
    -1
      src/core/plugins/split-pane-mode/components/split-pane-mode.jsx
  13. +0
    -5
      src/core/plugins/split-pane-mode/components/split-pane-mode.less
  14. +1
    -2
      src/core/plugins/util/index.js
  15. +71
    -45
      src/core/utils.js
  16. +1
    -1
      src/plugins/add-plugin.md
  17. +1
    -1
      src/plugins/topbar/topbar.jsx
  18. +0
    -52
      src/plugins/topbar/topbar.less
  19. +0
    -2
      src/standalone/index.js
  20. +9
    -1
      src/style/_buttons.scss
  21. +6
    -6
      src/style/_form.scss
  22. +9
    -0
      src/style/_layout.scss
  23. +6
    -0
      src/style/_mixins.scss
  24. +3
    -0
      src/style/_split-pane-mode.scss
  25. +4
    -0
      src/style/_table.scss
  26. +1
    -1
      src/style/main.scss
  27. +41
    -0
      test/components/schemes.js
  28. +0
    -183
      test/core/path-translator.js
  29. +301
    -36
      test/core/utils.js
  30. +12
    -44
      webpack-dist-bundle.config.js
  31. +11
    -44
      webpack-dist-standalone.config.js
  32. +9
    -50
      webpack-dist.config.js
  33. +24
    -33
      webpack-hot-dev-server.config.js
  34. +1
    -1
      webpack-watch.config.js
  35. +4
    -5
      webpack.check.js
  36. +1
    -1
      webpack.config.js
  37. +34
    -0
      webpack.dist-style.config.js

+ 5
- 0
README.md Visa fil

@@ -146,6 +146,7 @@ displayOperationId | Controls the display of operationId in operations list. The
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
deepLinking | If set to `true`, enables dynamic deep linking for tags and operations. [Docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/deep-linking.md)

### Plugins

@@ -235,6 +236,10 @@ Access-Control-Allow-Headers: Content-Type, api_key, Authorization

Only headers with these names will be allowed to be sent by Swagger-UI.

## Security contact

Please disclose any security-related issues or vulnerabilities by emailing [security@swagger.io](mailto:security@swagger.io), instead of using the public issue tracker.

## License

Copyright 2017 SmartBear Software


+ 1
- 0
dist/index.html Visa fil

@@ -76,6 +76,7 @@ window.onload = function() {
const ui = SwaggerUIBundle({
url: "http://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset


+ 0
- 1
make-webpack-config.js Visa fil

@@ -61,7 +61,6 @@ module.exports = function(rules, options) {
}

if( specialOptions.minimize ) {

plugins.push(
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,


+ 0
- 1
package.json Visa fil

@@ -109,7 +109,6 @@
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "2.0.3",
"less": "2.7.2",
"less-loader": "4.0.4",
"license-checker": "^11.0.0",
"mocha": "^3.4.2",
"node-sass": "^4.5.0",


+ 1
- 1
src/core/components/info.jsx Visa fil

@@ -15,7 +15,7 @@ class Path extends React.Component {

return (
<pre className="base-url">
[ Base url: {host}{basePath}]
[ Base URL: {host}{basePath} ]
</pre>
)
}


+ 4
- 3
src/core/components/layout-utils.jsx Visa fil

@@ -129,7 +129,8 @@ export class Select extends React.Component {
value: PropTypes.any,
onChange: PropTypes.func,
multiple: PropTypes.bool,
allowEmptyValue: PropTypes.bool
allowEmptyValue: PropTypes.bool,
className: PropTypes.string
}

static defaultProps = {
@@ -142,7 +143,7 @@ export class Select extends React.Component {

let value

if (props.value !== undefined) {
if (props.value) {
value = props.value
} else {
value = props.multiple ? [""] : ""
@@ -178,7 +179,7 @@ export class Select extends React.Component {
let value = this.state.value.toJS ? this.state.value.toJS() : this.state.value

return (
<select multiple={ multiple } value={ value } onChange={ this.onChange } >
<select className={this.props.className} multiple={ multiple } value={ value } onChange={ this.onChange } >
{ allowEmptyValue ? <option value="">--</option> : null }
{
allowedValues.map(function (item, key) {


+ 2
- 2
src/core/components/models.jsx Visa fil

@@ -24,8 +24,8 @@ export default class Models extends Component {
return <section className={ showModels ? "models is-open" : "models"}>
<h4 onClick={() => layoutActions.show("models", !showModels)}>
<span>Models</span>
<svg width="20" height="20">
<use xlinkHref="#large-arrow" />
<svg className="arrow" width="20" height="20">
<use xlinkHref={showModels ? "#large-arrow-down" : "#large-arrow"} />
</svg>
</h4>
<Collapse isOpened={showModels}>


+ 3
- 2
src/core/components/schemes.jsx Visa fil

@@ -19,8 +19,9 @@ export default class Schemes extends React.Component {
}

componentWillReceiveProps(nextProps) {
if ( this.props.operationScheme && !nextProps.schemes.has(this.props.operationScheme) ) {
//fire 'change' event if our selected scheme is no longer an option
if ( !this.props.operationScheme || !nextProps.schemes.has(this.props.operationScheme) ) {
// if we don't have a selected operationScheme or if our selected scheme is no longer an option,
// then fire 'change' event and select the first scheme in the list of options
this.setScheme(nextProps.schemes.first())
}
}


+ 13
- 11
src/core/json-schema-components.js Visa fil

@@ -57,7 +57,8 @@ export class JsonSchema_string extends Component {

if ( enumValue ) {
const Select = getComponent("Select")
return (<Select allowedValues={ enumValue }
return (<Select className={ errors.length ? "invalid" : ""}
allowedValues={ enumValue }
value={ value }
allowEmptyValue={ !required }
onChange={ this.onEnumChange }/>)
@@ -121,6 +122,7 @@ export class JsonSchema_array extends PureComponent {
render() {
let { getComponent, required, schema, fn } = this.props

let errors = schema.errors || []
let itemSchema = fn.inferSchema(schema.items)

const JsonSchemaForm = getComponent("JsonSchemaForm")
@@ -131,19 +133,17 @@ export class JsonSchema_array extends PureComponent {

if ( enumValue ) {
const Select = getComponent("Select")
return (<Select multiple={ true }
return (<Select className={ errors.length ? "invalid" : ""}
multiple={ true }
value={ value }
allowedValues={ enumValue }
allowEmptyValue={ !required }
onChange={ this.onEnumChange }/>)
}

let errors = schema.errors || []

return (
<div>
{ !value || value.count() < 1 ?
(errors.length ? <span style={{ color: "red", fortWeight: "bold" }}>{ errors[0] }</span> : null) :
{ !value || value.count() < 1 ? null :
value.map( (item,i) => {
let schema = Object.assign({}, itemSchema)
if ( errors.length ) {
@@ -153,12 +153,12 @@ export class JsonSchema_array extends PureComponent {
return (
<div key={i} className="json-schema-form-item">
<JsonSchemaForm fn={fn} getComponent={getComponent} value={item} onChange={(val) => this.onItemChange(val, i)} schema={schema} />
<Button className="json-schema-form-item-remove" onClick={()=> this.removeItem(i)} > - </Button>
<Button className="btn btn-sm json-schema-form-item-remove" onClick={()=> this.removeItem(i)} > - </Button>
</div>
)
}).toArray()
}
<Button className="json-schema-form-item-add" onClick={this.addItem}> Add item </Button>
<Button className={`btn btn-sm json-schema-form-item-add ${errors.length ? "invalid" : null}`} onClick={this.addItem}> Add item </Button>
</div>
)
}
@@ -170,12 +170,14 @@ export class JsonSchema_boolean extends Component {

onEnumChange = (val) => this.props.onChange(val)
render() {
let { getComponent, required, value } = this.props
let { getComponent, value, schema } = this.props
let errors = schema.errors || []
const Select = getComponent("Select")

return (<Select value={ String(value) }
return (<Select className={ errors.length ? "invalid" : ""}
value={ String(value) }
allowedValues={ fromJS(["true", "false"]) }
allowEmptyValue={ !required }
allowEmptyValue={true}
onChange={ this.onEnumChange }/>)
}
}

+ 0
- 67
src/core/path-translator.js Visa fil

@@ -1,67 +0,0 @@
import get from "lodash/get"

export function transformPathToArray(property, jsSpec) {
if(property.slice(0,9) === "instance.") {
var str = property.slice(9)
} else { // eslint-disable-next-line no-redeclare
var str = property
}

var pathArr = []

str
.split(".")
.map(item => {
// "key[0]" becomes ["key", "0"]
if(item.includes("[")) {
let index = parseInt(item.match(/\[(.*)\]/)[1])
let keyName = item.slice(0, item.indexOf("["))
return [keyName, index.toString()]
} else {
return item
}
})
.reduce(function(a, b) {
// flatten!
return a.concat(b)
}, [])
.concat([""]) // add an empty item into the array, so we don't get stuck with something in our buffer below
.reduce((buffer, curr) => {
let obj = pathArr.length ? get(jsSpec, pathArr) : jsSpec

if(get(obj, makeAccessArray(buffer, curr))) {
if(buffer.length) {
pathArr.push(buffer)
}
if(curr.length) {
pathArr.push(curr)
}
return ""
} else {
// attach key to buffer
return `${buffer}${buffer.length ? "." : ""}${curr}`
}
}, "")

if(typeof get(jsSpec, pathArr) !== "undefined") {
return pathArr
} else {
// if our path is not correct (there is no value at the path),
// return null
return null
}
}

function makeAccessArray(buffer, curr) {
let arr = []

if(buffer.length) {
arr.push(buffer)
}

if(curr.length) {
arr.push(curr)
}

return arr
}

+ 1
- 1
src/core/plugins/auth/actions.js Visa fil

@@ -73,7 +73,7 @@ export const authorizePassword = ( auth ) => ( { authActions } ) => {
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
let form = {
grant_type: "password",
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
scope: encodeURIComponent(auth.scopes.join(scopeSeparator))
}
let query = {}
let headers = {}


+ 0
- 1
src/core/plugins/split-pane-mode/components/split-pane-mode.jsx Visa fil

@@ -1,7 +1,6 @@
import React from "react"
import PropTypes from "prop-types"
import SplitPane from "react-split-pane"
import "./split-pane-mode.less"

const MODE_KEY = ["split-pane-mode"]
const MODE_LEFT = "left"


+ 0
- 5
src/core/plugins/split-pane-mode/components/split-pane-mode.less Visa fil

@@ -1,5 +0,0 @@
.swagger-ui {
.Resizer.vertical.disabled {
display: none;
}
}

+ 1
- 2
src/core/plugins/util/index.js Visa fil

@@ -1,8 +1,7 @@
import { shallowEqualKeys } from "core/utils"
import { transformPathToArray } from "core/path-translator"

export default function() {
return {
fn: { shallowEqualKeys, transformPathToArray }
fn: { shallowEqualKeys }
}
}

+ 71
- 45
src/core/utils.js Visa fil

@@ -41,7 +41,7 @@ export function fromJSOrdered (js) {
return !isObject(js) ? js :
Array.isArray(js) ?
Im.Seq(js).map(fromJSOrdered).toList() :
Im.Seq(js).map(fromJSOrdered).toOrderedMap()
Im.OrderedMap(js).map(fromJSOrdered)
}

export function bindToState(obj, state) {
@@ -468,6 +468,18 @@ export const validateFile = ( val ) => {
}
}

export const validateBoolean = ( val ) => {
if ( !(val === "true" || val === "false" || val === true || val === false) ) {
return "Value must be a boolean"
}
}

export const validateString = ( val ) => {
if ( val && typeof val !== "string" ) {
return "Value must be a string"
}
}

// validation of parameters before execute
export const validateParam = (param, isXml) => {
let errors = []
@@ -475,52 +487,66 @@ export const validateParam = (param, isXml) => {
let required = param.get("required")
let type = param.get("type")

let stringCheck = type === "string" && !value
let arrayCheck = type === "array" && Array.isArray(value) && !value.length
let listCheck = type === "array" && Im.List.isList(value) && !value.count()
let fileCheck = type === "file" && !(value instanceof win.File)

if ( required && (stringCheck || arrayCheck || listCheck || fileCheck) ) {
errors.push("Required field is not provided")
return errors
}

if ( value === null || value === undefined ) {
return errors
}

if ( type === "number" ) {
let err = validateNumber(value)
if (!err) return errors
errors.push(err)
} else if ( type === "integer" ) {
let err = validateInteger(value)
if (!err) return errors
errors.push(err)
} else if ( type === "array" ) {
let itemType

if ( !value.count() ) { return errors }

itemType = param.getIn(["items", "type"])

value.forEach((item, index) => {
let err
// If the parameter is required OR the parameter has a value (meaning optional, but filled in)
// then we should do our validation routine
if ( required || value ) {
// These checks should evaluate to true if the parameter's value is valid
let stringCheck = type === "string" && value && !validateString(value)
let arrayCheck = type === "array" && Array.isArray(value) && value.length
let listCheck = type === "array" && Im.List.isList(value) && value.count()
let fileCheck = type === "file" && value instanceof win.File
let booleanCheck = type === "boolean" && !validateBoolean(value)
let numberCheck = type === "number" && !validateNumber(value) // validateNumber returns undefined if the value is a number
let integerCheck = type === "integer" && !validateInteger(value) // validateInteger returns undefined if the value is an integer

if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
errors.push("Required field is not provided")
return errors
}

if (itemType === "number") {
err = validateNumber(item)
} else if (itemType === "integer") {
err = validateInteger(item)
}
if ( type === "string" ) {
let err = validateString(value)
if (!err) return errors
errors.push(err)
} else if ( type === "boolean" ) {
let err = validateBoolean(value)
if (!err) return errors
errors.push(err)
} else if ( type === "number" ) {
let err = validateNumber(value)
if (!err) return errors
errors.push(err)
} else if ( type === "integer" ) {
let err = validateInteger(value)
if (!err) return errors
errors.push(err)
} else if ( type === "array" ) {
let itemType

if ( !value.count() ) { return errors }

itemType = param.getIn(["items", "type"])

value.forEach((item, index) => {
let err

if (itemType === "number") {
err = validateNumber(item)
} else if (itemType === "integer") {
err = validateInteger(item)
} else if (itemType === "string") {
err = validateString(item)
}

if ( err ) {
errors.push({ index: index, error: err})
}
})
} else if ( type === "file" ) {
let err = validateFile(value)
if (!err) return errors
errors.push(err)
if ( err ) {
errors.push({ index: index, error: err})
}
})
} else if ( type === "file" ) {
let err = validateFile(value)
if (!err) return errors
errors.push(err)
}
}

return errors


+ 1
- 1
src/plugins/add-plugin.md Visa fil

@@ -20,7 +20,7 @@ SwaggerUI({
})
```

Or if you're updating the core plugins.. you'll add it to [src/js/bootstrap-plugin](https://github.com/SmartBear/swagger-ux/blob/master/src/js/bootstrap-plugin.js)
Or if you're updating the core plugins.. you'll add it to the base preset: [src/core/presets/base.js](https://github.com/swagger-api/swagger-ui/blob/master/src/core/presets/base.js)

Each Plugin is a function that returns an object. That object will get merged with the `system` and later bound to the state.
Here is an example of each `type`


+ 1
- 1
src/plugins/topbar/topbar.jsx Visa fil

@@ -130,7 +130,7 @@ export default class Topbar extends React.Component {
<div className="wrapper">
<div className="topbar-wrapper">
<Link href="#" title="Swagger UX">
<img height="30" width="30" src={ Logo } alt="Swagger UX"/>
<img height="30" width="30" src={ Logo } alt="Swagger UI"/>
<span>swagger</span>
</Link>
<form className="download-url-wrapper" onSubmit={formOnSubmit}>


+ 0
- 52
src/plugins/topbar/topbar.less Visa fil

@@ -1,52 +0,0 @@
.swagger-ui {
.topbar {
background-color: #89bf04;
}

.topbar-wrapper {
padding: 0.7em;
}

.topbar-logo__img {
float: left;
}

.topbar-logo__title {
display: inline-block;
color: #fff;
font-size: 1.5em;
font-weight: bold;
margin: 0.15em 0 0 0.5em;
}

.download-url-wrapper {
text-align: right;
float: right;
}

.topbar .download-url__text {
width: 28em;
height: 2em;
margin-right: 0.5em;
}

.download-url__btn {
background-color: #547f00;
border-color: #547f00;
text-decoration: none;
font-weight: bold;
padding: 0.2em 0.3em;
color: white;
border-radius: 0.1em;

&:hover {
&:extend(.download-url__btn);
}
}

.center-700 {
display: block;
margin: 0 auto;
width: 45em;
}
}

+ 0
- 2
src/standalone/index.js Visa fil

@@ -1,6 +1,4 @@
import StandaloneLayout from "./layout"
import "../style/main.scss"

import TopbarPlugin from "plugins/topbar"
import ConfigsPlugin from "plugins/configs"



+ 9
- 1
src/style/_buttons.scss Visa fil

@@ -14,6 +14,11 @@

@include text_headline();

&.btn-sm {
font-size: 12px;
padding: 4px 23px;
}

&[disabled]
{
cursor: not-allowed;
@@ -165,6 +170,9 @@
button
{
cursor: pointer;

outline: none;

&.invalid {
@include invalidFormElement();
}
}

+ 6
- 6
src/style/_form.scss Visa fil

@@ -21,6 +21,10 @@ select

background: #f7f7f7;
}

&.invalid {
@include invalidFormElement();
}
}

.opblock-body select
@@ -53,12 +57,8 @@ input[type=file]
border-radius: 4px;
background: #fff;

&.invalid
{
animation: shake .4s 1;

border-color: $_color-delete;
background: lighten($_color-delete, 35%);
&.invalid {
@include invalidFormElement();
}
}



+ 9
- 0
src/style/_layout.scss Visa fil

@@ -490,6 +490,15 @@
{
margin: 0;
}

a
{
@include text_code(#89bf04);
text-decoration: underline;
&:hover {
color: #81b10c;
}
}
}
}



+ 6
- 0
src/style/_mixins.scss Visa fil

@@ -166,3 +166,9 @@ $browser-context: 16;
@warn 'Breakpoint mixin supports: tablet, mobile, desktop';
}
}

@mixin invalidFormElement() {
animation: shake .4s 1;
border-color: $_color-delete;
background: lighten($_color-delete, 35%);
}

+ 3
- 0
src/style/_split-pane-mode.scss Visa fil

@@ -0,0 +1,3 @@
.Resizer.vertical.disabled {
display: none;
}

+ 4
- 0
src/style/_table.scss Visa fil

@@ -97,6 +97,10 @@ table
width: 100%;
max-width: 340px;
}

select {
border-width: 1px;
}
}

.parameter__name


+ 1
- 1
src/style/main.scss Visa fil

@@ -14,6 +14,6 @@
@import 'information';
@import 'authorize';
@import 'errors';

@include text_body();
@import 'split-pane-mode';
}

+ 41
- 0
test/components/schemes.js Visa fil

@@ -0,0 +1,41 @@

/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import { fromJS } from "immutable"
import Schemes from "components/schemes"

describe("<Schemes/>", function(){
it("calls props.specActions.setScheme() when no operationScheme is selected", function(){

// Given
let props = {
specActions: {
setScheme: createSpy()
},
schemes: fromJS([
"http",
"https"
]),
operationScheme: undefined,
path: "/test",
method: "get"
}
// When
let wrapper = shallow(<Schemes {...props}/>)

// Then operationScheme should default to first scheme in options list
expect(props.specActions.setScheme).toHaveBeenCalledWith("http", "/test" , "get")

// When the operationScheme is no longer in the list of options
props.schemes = fromJS([
"https"
])
wrapper.setProps(props)

// Then operationScheme should default to first scheme in options list
expect(props.specActions.setScheme).toHaveBeenCalledWith("https", "/test", "get")
})
})

+ 0
- 183
test/core/path-translator.js Visa fil

@@ -1,183 +0,0 @@
/* eslint-env mocha */
import expect from "expect"
import { transformPathToArray } from "core/path-translator"

describe("validation plugin - path translator", function(){

describe("string paths", function(){

it("should translate a simple string path to an array", function(){
// Given
let jsSpec = {
one: {
a: "a thing",
b: "another thing",
c: "one more thing"
},
two: 2
}

let path = "instance.one.a"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(["one", "a"])

})

it("should translate an ambiguous string path to an array", function(){
// Since JSONSchema uses periods to mark different properties,
// a key with a period in it is ambiguous, because it can mean at least two things.
// In our case, the path can mean:
// ["google", "com", "a"] or ["google.com", "a"]

// Given
let jsSpec = {
"google.com": {
a: "a thing",
b: "another thing",
c: "one more thing"
},
"gmail.com": {
d: "more stuff",
e: "even more stuff"
}
}

let path = "instance.google.com.a"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a"])

})

it("should translate an doubly ambiguous string path to an array", function(){
// Since JSONSchema uses periods to mark different properties,
// a key with two periods in it (like "www.google.com") is doubly ambiguous,
// because it can mean at least three things.


// Given
let jsSpec = {
"www.google.com": {
a: "a thing",
b: "another thing",
c: "one more thing"
},
"gmail.com": {
d: "more stuff",
e: "even more stuff"
}
}

let path = "instance.www.google.com.a"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(["www.google.com", "a"])

})

it("should return null for an invalid path", function(){

// Given
let jsSpec = {
"google.com": {
a: "a thing",
b: "another thing",
c: "one more thing"
},
"gmail.com": {
d: "more stuff",
e: "even more stuff"
}
}

let path = "instance.google.net.a"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(null)

})

it("should return inline array indices in their own value", function(){
// "a[1]" => ["a", "1"]

// Given
let jsSpec = {
"google.com": {
a: [
"hello",
"here is the target"
],
b: "another thing",
c: "one more thing"
},
"gmail.com": {
d: "more stuff",
e: "even more stuff"
}
}

let path = "instance.google.com.a[1]"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a", "1"])

})

it("should return the correct path when the last part is ambiguous", function(){

// Given
let jsSpec = {
"google.com": {
a: [
"hello",
{
"gmail.com": 1234
}
],
b: "another thing",
c: "one more thing"
},
"gmail.com": {
d: "more stuff",
e: "even more stuff"
}
}

let path = "instance.google.com.a[1].gmail.com"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a", "1", "gmail.com"])

})

it("should return the correct path when the last part is doubly ambiguous", function(){

// Given
let jsSpec = {
"google.com": {
a: [
"hello",
{
"www.gmail.com": 1234
}
],
b: "another thing",
c: "one more thing"
},
"gmail.com": {
d: "more stuff",
e: "even more stuff"
}
}

let path = "instance.google.com.a[1].www.gmail.com"

// Then
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a", "1", "www.gmail.com"])

})

})

})

+ 301
- 36
test/core/utils.js Visa fil

@@ -1,10 +1,10 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import { mapToList, validateNumber, validateInteger, validateParam, validateFile } from "core/utils"
import { mapToList, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered } from "core/utils"
import win from "core/window"

describe("utils", function(){
describe("utils", function() {

describe("mapToList", function(){

@@ -176,6 +176,7 @@ describe("utils", function(){
let result = null

it("validates required strings", function() {
// invalid string
param = fromJS({
required: true,
type: "string",
@@ -183,9 +184,39 @@ describe("utils", function(){
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// valid string
param = fromJS({
required: true,
type: "string",
value: "test string"
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates optional strings", function() {
// valid (empty) string
param = fromJS({
required: false,
type: "string",
value: ""
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// valid string
param = fromJS({
required: false,
type: "string",
value: "test"
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates required files", function() {
// invalid file
param = fromJS({
required: true,
type: "file",
@@ -193,9 +224,48 @@ describe("utils", function(){
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// valid file
param = fromJS({
required: true,
type: "file",
value: new win.File()
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates optional files", function() {
// invalid file
param = fromJS({
required: false,
type: "file",
value: "not a file"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be a file"] )

// valid (empty) file
param = fromJS({
required: false,
type: "file",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// valid file
param = fromJS({
required: false,
type: "file",
value: new win.File()
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates required arrays", function() {
// invalid (empty) array
param = fromJS({
required: true,
type: "array",
@@ -204,17 +274,191 @@ describe("utils", function(){
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// invalid (not an array)
param = fromJS({
required: true,
type: "array",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// invalid array, items do not match correct type
param = fromJS({
required: true,
type: "array",
value: [1],
items: {
type: "string"
}
})
result = validateParam( param, false )
expect( result ).toEqual( [{index: 0, error: "Value must be a string"}] )

// valid array, with no 'type' for items
param = fromJS({
required: true,
type: "array",
value: ["1"]
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// valid array, items match type
param = fromJS({
required: true,
type: "array",
value: ["1"],
items: {
type: "string"
}
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates optional arrays", function() {
// valid, empty array
param = fromJS({
required: false,
type: "array",
value: []
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// invalid, items do not match correct type
param = fromJS({
required: false,
type: "array",
value: ["number"],
items: {
type: "number"
}
})
result = validateParam( param, false )
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )

// valid
param = fromJS({
required: false,
type: "array",
value: ["test"],
items: {
type: "string"
}
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates required booleans", function() {
// invalid boolean value
param = fromJS({
required: true,
type: "boolean",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// invalid boolean value (not a boolean)
param = fromJS({
required: true,
type: "boolean",
value: "test string"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// valid boolean value
param = fromJS({
required: true,
type: "boolean",
value: "true"
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// valid boolean value
param = fromJS({
required: true,
type: "boolean",
value: false
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates numbers", function() {
// string instead of a number
it("validates optional booleans", function() {
// valid (empty) boolean value
param = fromJS({
required: false,
type: "boolean",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// invalid boolean value (not a boolean)
param = fromJS({
required: false,
type: "boolean",
value: "test string"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be a boolean"] )

// valid boolean value
param = fromJS({
required: false,
type: "boolean",
value: "true"
})
result = validateParam( param, false )
expect( result ).toEqual( [] )

// valid boolean value
param = fromJS({
required: false,
type: "boolean",
value: false
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates required numbers", function() {
// invalid number, string instead of a number
param = fromJS({
required: true,
type: "number",
value: "test"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// invalid number, undefined value
param = fromJS({
required: true,
type: "number",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )

// valid number
param = fromJS({
required: true,
type: "number",
value: 10
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates optional numbers", function() {
// invalid number, string instead of a number
param = fromJS({
required: false,
type: "number",
@@ -223,7 +467,7 @@ describe("utils", function(){
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be a number"] )

// undefined value
// valid (empty) number
param = fromJS({
required: false,
type: "number",
@@ -232,78 +476,99 @@ describe("utils", function(){
result = validateParam( param, false )
expect( result ).toEqual( [] )

// null value
// valid number
param = fromJS({
required: false,
type: "number",
value: null
value: 10
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates integers", function() {
// string instead of integer
it("validates required integers", function() {
// invalid integer, string instead of an integer
param = fromJS({
required: false,
required: true,
type: "integer",
value: "test"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be an integer"] )
expect( result ).toEqual( ["Required field is not provided"] )

// undefined value
// invalid integer, undefined value
param = fromJS({
required: false,
required: true,
type: "integer",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
expect( result ).toEqual( ["Required field is not provided"] )

// null value
// valid integer
param = fromJS({
required: false,
required: true,
type: "integer",
value: null
value: 10
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})

it("validates arrays", function() {
// empty array
it("validates optional integers", function() {
// invalid integer, string instead of an integer
param = fromJS({
required: false,
type: "array",
value: []
type: "integer",
value: "test"
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
expect( result ).toEqual( ["Value must be an integer"] )

// numbers
// valid (empty) integer
param = fromJS({
required: false,
type: "array",
value: ["number"],
items: {
type: "number"
}
type: "integer",
value: undefined
})
result = validateParam( param, false )
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )
expect( result ).toEqual( [] )

// integers
// valid number
param = fromJS({
required: false,
type: "array",
value: ["not", "numbers"],
items: {
type: "integer"
}
type: "integer",
value: 10
})
result = validateParam( param, false )
expect( result ).toEqual( [{index: 0, error: "Value must be an integer"}, {index: 1, error: "Value must be an integer"}] )
expect( result ).toEqual( [] )
})
})

describe("fromJSOrdered", () => {
it("should create an OrderedMap from an object", () => {
const param = {
value: "test"
}

const result = fromJSOrdered(param).toJS()
expect( result ).toEqual( { value: "test" } )
})

it("should not use an object's length property for Map size", () => {
const param = {
length: 5
}

const result = fromJSOrdered(param).toJS()
expect( result ).toEqual( { length: 5 } )
})

it("should create an OrderedMap from an array", () => {
const param = [1, 1, 2, 3, 5, 8]

const result = fromJSOrdered(param).toJS()
expect( result ).toEqual( [1, 1, 2, 3, 5, 8] )
})
})
})

+ 12
- 44
webpack-dist-bundle.config.js Visa fil

@@ -1,64 +1,32 @@
var path = require('path')
var rules = [
const path = require("path")
const styleRules = require("./webpack.dist-style.config.js")

let rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
loader: "worker-loader",
options: {
inline: true,
name: '[name].js'
}
},
{ loader: 'babel-loader' }
]
},
{ test: /\.(css)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
},
{ test: /\.(scss)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
name: "[name].js"
}
}
]
},
{ test: /\.(less)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
{ loader: "babel-loader" }
]
}
]

module.exports = require('./make-webpack-config.js')(rules, {
module.exports = require("./make-webpack-config.js")(rules, {
_special: {
separateStylesheets: false,
separateStylesheets: true,
minimize: true,
sourcemaps: true,
},

entry: {
'swagger-ui-bundle': [
'./src/polyfills',
'./src/core/index.js'
"swagger-ui-bundle": [
"./src/polyfills",
"./src/core/index.js"
]
},



+ 11
- 44
webpack-dist-standalone.config.js Visa fil

@@ -1,65 +1,32 @@
var path = require('path')
const path = require("path")
const styleRules = require("./webpack.dist-style.config.js")

var rules = [
let rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
loader: "worker-loader",
options: {
inline: true,
name: '[name].js'
name: "[name].js"
}
},
{ loader: 'babel-loader' }
]
},
{ test: /\.(css)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
},
{ test: /\.(scss)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
}
}
]
},
{ test: /\.(less)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
{ loader: "babel-loader" }
]
}
]

module.exports = require('./make-webpack-config.js')(rules, {
module.exports = require("./make-webpack-config.js")(rules, {
_special: {
separateStylesheets: false,
separateStylesheets: true,
minimize: true,
sourcemaps: true,
},

entry: {
'swagger-ui-standalone-preset': [
'./src/polyfills',
'./src/standalone/index.js'
"swagger-ui-standalone-preset": [
"./src/polyfills",
"./src/standalone/index.js"
]
},



+ 9
- 50
webpack-dist.config.js Visa fil

@@ -1,66 +1,25 @@
var path = require('path')
var fs = require('fs')
const path = require("path")
const fs = require("fs")
const nodeModules = fs.readdirSync("node_modules").filter(function(x) { return x !== ".bin" })
var ExtractTextPlugin = require('extract-text-webpack-plugin')
const styleRules = require("./webpack.dist-style.config.js")

var rules = [
let rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
loader: "worker-loader",
options: {
inline: true,
name: '[name].js'
name: "[name].js"
}
},
{ loader: 'babel-loader' }
{ loader: "babel-loader" }
]
},
{ test: /\.(css)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'postcss-loader'
]
})
},
{ test: /\.(scss)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: { minimize: true }
},
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
}
}
]
})
},
{ test: /\.(less)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
]
})
}
]
rules = rules.concat(styleRules)

module.exports = require('./make-webpack-config.js')(rules, {
module.exports = require("./make-webpack-config.js")(rules, {
_special: {
separateStylesheets: true,
minimize: true,


+ 24
- 33
webpack-hot-dev-server.config.js Visa fil

@@ -1,56 +1,46 @@
var path = require('path')
const path = require("path")

var rules = [
const rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
loader: "worker-loader",
options: {
inline: true
}
},
{ loader: 'babel-loader' }
{ loader: "babel-loader" }
]
},
{ test: /\.(jsx)(\?.*)?$/,
use: [
{ loader: 'react-hot-loader' },
{ loader: 'babel-loader' }
{ loader: "react-hot-loader" },
{ loader: "babel-loader" }
]
},
{ test: /\.(css)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
"style-loader",
"css-loader",
"postcss-loader"
]
},
{ test: /\.(scss)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
"style-loader",
"css-loader",
{
loader: 'postcss-loader',
loader: "postcss-loader",
options: { sourceMap: true }
},
{ loader: 'sass-loader',
{ loader: "sass-loader",
options: {
outputStyle: 'expanded',
outputStyle: "expanded",
sourceMap: true,
sourceMapContents: 'true'
sourceMapContents: "true"
}
}
]
},
{ test: /\.(less)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
]
}
]

@@ -60,25 +50,26 @@ module.exports = require("./make-webpack-config")(rules, {
},
devtool: "eval",
entry: {
'swagger-ui-bundle': [
'./src/polyfills',
'./src/core/index.js'
"swagger-ui-bundle": [
"./src/polyfills",
"./src/core/index.js"
],
'swagger-ui-standalone-preset': [
'./src/polyfills',
'./src/standalone/index.js',
"swagger-ui-standalone-preset": [
"./src/style/main.scss",
"./src/polyfills",
"./src/standalone/index.js",
]
},
output: {
pathinfo: true,
filename: '[name].js',
filename: "[name].js",
library: "[name]",
libraryTarget: "umd",
chunkFilename: "[id].js"
},
devServer: {
port: 3200,
contentBase: path.join(__dirname, 'dev-helpers'),
contentBase: path.join(__dirname, "dev-helpers"),
publicPath: "/",
noInfo: true,
hot: true,


+ 1
- 1
webpack-watch.config.js Visa fil

@@ -1,3 +1,3 @@
var config = require("./webpack-dist.config.js")
const config = require("./webpack-dist.config.js")

module.exports = config

+ 4
- 5
webpack.check.js Visa fil

@@ -1,8 +1,7 @@
const webpack = require('webpack')
const path = require('path')
const deepMerge = require('deepmerge')
const webpackConfig = require('./webpack-dist-bundle.config.js')
const DEPS_CHECK_DIR = require('./package.json').config.deps_check_dir
const path = require("path")
const deepMerge = require("deepmerge")
const webpackConfig = require("./webpack-dist-bundle.config.js")
const DEPS_CHECK_DIR = require("./package.json").config.deps_check_dir

module.exports = deepMerge(
webpackConfig, {


+ 1
- 1
webpack.config.js Visa fil

@@ -1,3 +1,3 @@
module.exports = require("./make-webpack-config")({

});
})

+ 34
- 0
webpack.dist-style.config.js Visa fil

@@ -0,0 +1,34 @@
const ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = [{
test: /\.(css)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
"css-loader",
"postcss-loader"
]
})
},
{ test: /\.(scss)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: "css-loader",
options: { minimize: true }
},
{
loader: "postcss-loader",
options: { sourceMap: true }
},
{ loader: "sass-loader",
options: {
outputStyle: "expanded",
sourceMap: true,
sourceMapContents: "true"
}
}
]
})
}]

Laddar…
Avbryt
Spara