diff --git a/docs/authoring_apps.md b/docs/authoring_apps.md index e7159e2436..9f8a14a0c1 100644 --- a/docs/authoring_apps.md +++ b/docs/authoring_apps.md @@ -15,12 +15,21 @@ The main thing to keep in mind when working with `cache` is that it's scoped per Config is used to configure an app. It's a key/value pair of config values and is passed into `main`. It's exposed through query parameters in the url of `pixlet serve` or through command line args through `pixlet render`. When publishing apps to the Tidbyt [Community](https://github.com/tidbyt/community) repo, the Tidbyt backend will populate the config values from values provided in the mobile app. The important thing to remember here is that your app should always be able to render even if a config value isn't provided. Providing default values for every config value or checking it for `None` will ensure the app behaves as expected even if config was not provided. For example, the following ensures there will always be a value for `foo`: -``` + +```starlark DEFAULT_FOO = "bar" def main(config): foo = config.get("foo", DEFAULT_FOO) ``` +The `config` object also has helpers to convert config values into specific types: + +```starlark +config.str("foo") # returns a string, or None if not found +config.bool("foo") # returns a boolean (True or False), or None if not found +``` + + ## Fail Using a `fail()` inside of your app should be used incredibly sparingly. It kills the entire execution in an unrecoverable fashion. If your app depends on an external API, it cannot cache the response, and has no means of recovering with a failed response - then a `fail()` is appropriate. Otherwise, using a `print()` and handling the error appropriately is a better approach. \ No newline at end of file diff --git a/docs/schema.md b/docs/schema.md index a6ca4a4753..e5d47af192 100644 --- a/docs/schema.md +++ b/docs/schema.md @@ -6,7 +6,7 @@ The way it works is quite simple. We call `get_schema` and supply the fields to > Note: Schema is for configuring apps submitted to [Community Apps](https://github.com/tidbyt/community). We're working on adding tighter integration into Pixlet so that pixlet commands make better use of schema. ## Quick Start -Let's add a toggle to our hello world example. Here it is before we add schema: +Let's add a toggle and a text input to our hello world example. Here it is before we add schema: ```starlark load("render.star", "render") @@ -22,11 +22,15 @@ This is a quick start, so let's start with the code and we'll break it down: load("render.star", "render") load("schema.star", "schema") +DEFAULT_WHO = "World" + def main(config): - if config.get("small"): - msg = render.Text("Hello, World!", font = "CG-pixel-3x5-mono") + message = "Hello, %s!" % config.str("who", DEFAULT_WHO) + + if config.bool("small"): + msg = render.Text(message, font = "CG-pixel-3x5-mono") else: - msg = render.Text("Hello, World!") + msg = render.Text(message) return render.Root( child = msg, @@ -36,6 +40,12 @@ def get_schema(): return schema.Schema( version = "1", fields = [ + schema.Text( + id = "who", + name = "Who?", + desc = "Who to say hello to.", + icon = "user", + ), schema.Toggle( id = "small", name = "Display small text", @@ -49,9 +59,9 @@ def get_schema(): The big change here is the `get_schema` method. This is the method we will call before rendering your app when running inside of our [Community Apps](https://github.com/tidbyt/community) repo. A quick note - we don't call this method using Pixlet at this time. -The `get_schema` method returns a `schema.Schema` object that contains _fields_. See below for a complete breakdown of what config options are available. In our example, we'll use a toggle. +The `get_schema` method returns a `schema.Schema` object that contains _fields_. See below for a complete breakdown of what config options are available. In our example, we use a toggle and a text input. -Next up should be more familiar. We're now passing `config` into `main()`. This is the same for current pixlet scripts that take `config` today. In [Community Apps](https://github.com/tidbyt/community), we will populate the config hashmap with values configured from the mobile app. More specifically, `config` is a key/value pair where the key is the `id` of the schema field and the value is determined by the user in the mobile app. +Next up should be more familiar. We're now passing `config` into `main()`. This is the same for current pixlet scripts that take `config` today. In [Community Apps](https://github.com/tidbyt/community), we will populate the config hashmap with values configured from the mobile app. That's about it! diff --git a/examples/schema_hello_world.star b/examples/schema_hello_world.star index 07966b7b10..38c6b453c5 100644 --- a/examples/schema_hello_world.star +++ b/examples/schema_hello_world.star @@ -2,10 +2,12 @@ load("render.star", "render") load("schema.star", "schema") def main(config): - if config.get("small"): - msg = render.Text("Hello, World!", font = "CG-pixel-3x5-mono") + message = "Hello, %s!" % config.get("who", "World") + + if config.bool("small"): + msg = render.Text(message, font = "CG-pixel-3x5-mono") else: - msg = render.Text("Hello, World!") + msg = render.Text(message) return render.Root( child = msg, @@ -15,6 +17,12 @@ def get_schema(): return schema.Schema( version = "1", fields = [ + schema.Text( + id = "who", + name = "Who?", + desc = "Who to say hello to.", + icon = "user", + ), schema.Toggle( id = "small", name = "Display small text", diff --git a/runtime/config.go b/runtime/config.go new file mode 100644 index 0000000000..93e53613c2 --- /dev/null +++ b/runtime/config.go @@ -0,0 +1,94 @@ +package runtime + +import ( + "fmt" + "strconv" + + "github.com/mitchellh/hashstructure/v2" + "go.starlark.net/starlark" +) + +type AppletConfig map[string]string + +func (a AppletConfig) AttrNames() []string { + return []string{ + "get", + "str", + "bool", + } +} + +func (a AppletConfig) Attr(name string) (starlark.Value, error) { + switch name { + + case "get", "str": + return starlark.NewBuiltin("str", a.getString), nil + + case "bool": + return starlark.NewBuiltin("bool", a.getBoolean), nil + + default: + return nil, nil + } +} + +func (a AppletConfig) Get(key starlark.Value) (starlark.Value, bool, error) { + switch v := key.(type) { + case starlark.String: + val, found := a[v.GoString()] + return starlark.String(val), found, nil + default: + return nil, false, nil + } +} + +func (a AppletConfig) String() string { return "AppletConfig(...)" } +func (a AppletConfig) Type() string { return "AppletConfig" } +func (a AppletConfig) Freeze() {} +func (a AppletConfig) Truth() starlark.Bool { return true } + +func (a AppletConfig) Hash() (uint32, error) { + sum, err := hashstructure.Hash(a, hashstructure.FormatV2, nil) + return uint32(sum), err +} + +func (a AppletConfig) getString(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var key starlark.String + var def starlark.Value + def = starlark.None + + if err := starlark.UnpackPositionalArgs( + "str", args, kwargs, 1, + &key, &def, + ); err != nil { + return nil, fmt.Errorf("unpacking arguments for config.str: %v", err) + } + + val, ok := a[key.GoString()] + if !ok { + return def, nil + } else { + return starlark.String(val), nil + } +} + +func (a AppletConfig) getBoolean(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var key starlark.String + var def starlark.Value + def = starlark.None + + if err := starlark.UnpackPositionalArgs( + "bool", args, kwargs, 1, + &key, &def, + ); err != nil { + return nil, fmt.Errorf("unpacking arguments for config.bool: %v", err) + } + + val, ok := a[key.GoString()] + if !ok { + return def, nil + } else { + b, _ := strconv.ParseBool(val) + return starlark.Bool(b), nil + } +} diff --git a/runtime/runtime.go b/runtime/runtime.go index 72924458da..722c563399 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -3,11 +3,7 @@ package runtime import ( "context" "crypto/md5" - "encoding/json" "fmt" - "log" - "strconv" - "strings" "github.com/pkg/errors" starlibbase64 "github.com/qri-io/starlib/encoding/base64" @@ -20,6 +16,7 @@ import ( "go.starlark.net/resolve" "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" + "go.starlark.net/starlarktest" "tidbyt.dev/pixlet/render" "tidbyt.dev/pixlet/runtime/modules/sunrise" @@ -43,16 +40,15 @@ func init() { } type Applet struct { - Filename string - Id string - Globals starlark.StringDict - src []byte - loader ModuleLoader - predeclared starlark.StringDict - main *starlark.Function - - schema *schema.Schema - schemaJSON []byte + Filename string + Id string + Globals starlark.StringDict + src []byte + loader ModuleLoader + predeclared starlark.StringDict + main *starlark.Function + schema string + schemaHandler map[string]schema.SchemaHandler } func (a *Applet) thread(initializers ...ThreadInitializer) *starlark.Thread { @@ -108,6 +104,8 @@ func (a *Applet) Load(filename string, src []byte, loader ModuleLoader) (err err } a.main = main + var s string + var handlers map[string]schema.SchemaHandler schemaFun, _ := a.Globals[schema.SchemaFunctionName].(*starlark.Function) if schemaFun != nil { schemaVal, err := a.Call(schemaFun, nil) @@ -115,17 +113,15 @@ func (a *Applet) Load(filename string, src []byte, loader ModuleLoader) (err err return errors.Wrap(err, "calling schema function") } - a.schema, err = schema.FromStarlark(schemaVal, a.Globals) + s, handlers, err = schema.EncodeSchema(schemaVal, a.Globals) if err != nil { - return errors.Wrap(err, "parsing Starlark schema") - } - - a.schemaJSON, err = json.Marshal(a.schema) - if err != nil { - return errors.Wrap(err, "serializing schema to JSON") + return errors.Wrap(err, "encode schema") } } + a.schema = s + a.schemaHandler = handlers + return nil } @@ -134,29 +130,7 @@ func (a *Applet) Load(filename string, src []byte, loader ModuleLoader) (err err func (a *Applet) Run(config map[string]string, initializers ...ThreadInitializer) (roots []render.Root, err error) { var args starlark.Tuple if a.main.NumParams() > 0 { - starlarkConfig := starlark.NewDict(len(config)) - for k, v := range config { - var starlarkVal starlark.Value - starlarkVal = starlark.String(v) - - if strings.HasPrefix(k, "$") { - // this a special field like "$tz". no need to check the schema - } else if a.schema != nil { - // app has a schema, so we can provide strongly typed config values - field := a.schema.Field(k) - - if field == nil { - // we have a value, but it's not part of the app's schema. - // allow it for now, but we will deprecate it in the future. - log.Printf("received config value for '%s', but it is not in the schema for %s", k, a.Filename) - } else if field.Type == "onoff" { - b, _ := strconv.ParseBool(v) - starlarkVal = starlark.Bool(b) - } - } - - starlarkConfig.SetKey(starlark.String(k), starlarkVal) - } + starlarkConfig := AppletConfig(config) args = starlark.Tuple{starlarkConfig} } @@ -195,7 +169,7 @@ func (a *Applet) Run(config map[string]string, initializers ...ThreadInitializer // CallSchemaHandler calls the schema handler for a field, passing it a single // string parameter and returning a single string value. func (app *Applet) CallSchemaHandler(ctx context.Context, fieldId, parameter string) (result string, err error) { - handler, found := app.schema.Handlers[fieldId] + handler, found := app.schemaHandler[fieldId] if !found { return "", fmt.Errorf("no handler exported for field id %s", fieldId) } @@ -218,17 +192,11 @@ func (app *Applet) CallSchemaHandler(ctx context.Context, fieldId, parameter str return options, nil case schema.ReturnSchema: - sch, err := schema.FromStarlark(resultVal, app.Globals) + schema, _, err := schema.EncodeSchema(resultVal, app.Globals) if err != nil { - return "", errors.Wrap(err, "parsing Starlark schema") - } - - s, err := json.Marshal(sch) - if err != nil { - return "", errors.Wrap(err, "serializing schema to JSON") + return "", err } - - return string(s), nil + return schema, nil case schema.ReturnString: str, ok := starlark.AsString(resultVal) @@ -244,9 +212,9 @@ func (app *Applet) CallSchemaHandler(ctx context.Context, fieldId, parameter str return "", fmt.Errorf("a very unexpected error happened for field \"%s\"", fieldId) } -// GetSchema returns the serialized schema for the applet. +// GetSchema returns the config for the applet. func (app *Applet) GetSchema() string { - return string(app.schemaJSON) + return app.schema } func attachContext(ctx context.Context) ThreadInitializer { @@ -333,6 +301,9 @@ func (a *Applet) loadModule(thread *starlark.Thread, module string) (starlark.St starlibtime.Module.Name: starlibtime.Module, }, nil + case "assert.star": + return starlarktest.LoadAssertModule() + default: return nil, fmt.Errorf("invalid module: %s", module) } diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go index 2007e9069c..05b5c6ec1d 100644 --- a/runtime/runtime_test.go +++ b/runtime/runtime_test.go @@ -6,6 +6,7 @@ import ( starlibbase64 "github.com/qri-io/starlib/encoding/base64" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.starlark.net/starlark" ) @@ -125,9 +126,10 @@ def main(): func TestRunMainAcceptsConfig(t *testing.T) { config := map[string]string{ - "$tz": "UTC", - "one": "1", - "two": "2", + "one": "1", + "two": "2", + "toggle1": "true", + "toggle2": "false", } // It's ok for main() to accept no args at all @@ -146,75 +148,32 @@ def main(): // And it can accept a (the) config dict src = ` load("render.star", "render") + +def assert_eq(message, actual, expected): + if not expected == actual: + fail(message, "-", "expected", expected, "actual", actual) + def main(config): - expected_tz = "UTC" - actual_tz = config.get("$tz") + assert_eq("config.get with fallback", config.get("doesnt_exist", "foo"), "foo") + + assert_eq("config.str with fallback", config.str("doesnt_exist", "foo"), "foo") + assert_eq("config.str non-existent value", config.str("doesnt_exist"), None) - if actual_tz != expected_tz: - fail("$tz - expected", expected_tz, "got", actual_tz) + assert_eq("config.bool with fallback", config.bool("doesnt_exist", True), True) + assert_eq("config.bool non-existent value", config.bool("doesnt_exist"), None) + + assert_eq("config.bool('toggle1')", config.bool("toggle1"), True) + assert_eq("config.bool('toggle2')", config.bool("toggle2"), False) return [render.Root(child=render.Box()) for _ in range(int(config["one"]) + int(config["two"]))] ` app = &Applet{} err = app.Load("test.star", []byte(src), nil) - assert.NoError(t, err) + require.NoError(t, err) roots, err = app.Run(config) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, 3, len(roots)) } -func TestRunMainAcceptsConfigWithSchema(t *testing.T) { - config := map[string]string{ - "$tz": "UTC", - "small": "true", - "not_in_schema": "foo", - } - - src := ` -load("render.star", "render") -load("schema.star", "schema") - -def main(config): - expected_tz = "UTC" - actual_tz = config.get("$tz") - - if actual_tz != expected_tz: - fail("$tz - expected", expected_tz, "got", actual_tz) - - expected_small = True - actual_small = config.get("small") - - if actual_small != expected_small: - fail("small - expected", expected_small, "got", actual_small) - - expected_not_in_schema = None - actual_not_in_schema = config.get("not_in_schema") - - if actual_not_in_schema != expected_not_in_schema: - pass # this is actually allowed for now - # fail("not_in_schema - expected", expected_not_in_schema, "got", actual_not_in_schema) - - return [] - -def get_schema(): - return schema.Schema( - version = "1", - fields = [ - schema.Toggle( - id = "small", - name = "Display small text", - desc = "A toggle to display smaller text.", - icon = "compress", - default = False, - ), - ], - ) -` - app := &Applet{} - err := app.Load("test.star", []byte(src), nil) - assert.NoError(t, err) - _, err = app.Run(config) - assert.NoError(t, err) -} func TestModuleLoading(t *testing.T) { // Our basic set of modules can be imported diff --git a/schema/module.go b/schema/module.go index 3a1d92d992..fb342da0bd 100644 --- a/schema/module.go +++ b/schema/module.go @@ -68,7 +68,7 @@ func newSchema(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple s := &StarlarkSchema{} s.Version = version.GoString() - s.Schema.Fields = []SchemaField{} + s.Schema.Schema = []SchemaField{} var fieldVal starlark.Value fieldIter := fields.Iterate() @@ -87,7 +87,7 @@ func newSchema(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple ) } - s.Schema.Fields = append(s.Schema.Fields, f.AsSchemaField()) + s.Schema.Schema = append(s.Schema.Schema, f.AsSchemaField()) } s.starlarkFields = fields diff --git a/schema/module_test.go b/schema/module_test.go index 1040d63945..9f13a9d5bc 100644 --- a/schema/module_test.go +++ b/schema/module_test.go @@ -29,7 +29,6 @@ s = schema.Schema( name = "Display Weather", desc = "A toggle to determine if the weather should be displayed.", icon = "cloud", - default = False, ), ], ) diff --git a/schema/schema.go b/schema/schema.go index 8ee99f45c6..d1718c5094 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -26,11 +26,8 @@ const ( // Schema holds a configuration object for an applet. It holds a list of fileds // that are exported from an applet. type Schema struct { - Version string `json:"version" validate:"required"` - Fields []SchemaField `json:"schema" validate:"required,dive"` - Handlers map[string]SchemaHandler `json:"-"` - - fieldByID map[string]*SchemaField + Version string `json:"version" validate:"required"` + Schema []SchemaField `json:"schema" validate:"required,dive"` } // SchemaField represents an item in the config used to confgure an applet. @@ -81,46 +78,38 @@ type SchemaHandler struct { ReturnType HandlerReturnType } -// Field returns a pointer to the schema field with the given ID, or nil if it -// doesn't exist. -func (s *Schema) Field(id string) *SchemaField { - return s.fieldByID[id] -} - -// FromStarlark creates a new Schema from a Starlark schema object. -func FromStarlark( +// Encodes a starlark config schema into validated json and extracts +// all schema handlers. +func EncodeSchema( starlarkSchema starlark.Value, - globals starlark.StringDict) (*Schema, error) { + globals starlark.StringDict) (string, map[string]SchemaHandler, error) { schemaTree, err := unmarshalStarlark(starlarkSchema) if err != nil { - return nil, err + return "", nil, err } treeJSON, err := json.Marshal(schemaTree) if err != nil { - return nil, err + return "", nil, err } - schema := &Schema{Version: "1", - Handlers: make(map[string]SchemaHandler), - fieldByID: make(map[string]*SchemaField), - } - if err := json.Unmarshal(treeJSON, &schema.Fields); err != nil { - return nil, err + schema := &Schema{Version: "1"} + if err := json.Unmarshal(treeJSON, &schema.Schema); err != nil { + return "", nil, err } err = validateSchema(schema) if err != nil { - return nil, err + return "", nil, err } - for i, schemaField := range schema.Fields { - schema.fieldByID[schemaField.ID] = &schema.Fields[i] + handlers := map[string]SchemaHandler{} + for i, schemaField := range schema.Schema { if schemaField.Handler != "" { handlerValue, found := globals[schemaField.Handler] if !found { - return nil, fmt.Errorf( + return "", nil, fmt.Errorf( "field %d references non-existent handler \"%s\"", i, schemaField.Handler) @@ -128,7 +117,7 @@ func FromStarlark( handlerFun, ok := handlerValue.(*starlark.Function) if !ok { - return nil, fmt.Errorf( + return "", nil, fmt.Errorf( "field %d references \"%s\" which is not a function", i, schemaField.Handler) } @@ -146,16 +135,21 @@ func FromStarlark( case "oauth1": handlerType = ReturnString default: - return nil, fmt.Errorf( + return "", nil, fmt.Errorf( "field %d of type \"%s\" can't have a handler function", i, schemaField.Type) } - schema.Handlers[schemaField.ID] = SchemaHandler{Function: handlerFun, ReturnType: handlerType} + handlers[schemaField.ID] = SchemaHandler{Function: handlerFun, ReturnType: handlerType} } } - return schema, nil + schemaJSON, err := json.Marshal(schema) + if err != nil { + return "", nil, err + } + + return string(schemaJSON), handlers, nil } // Encodes a list of schema options into validated json. @@ -194,7 +188,7 @@ func unmarshalStarlark(object starlark.Value) (interface{}, error) { switch v := object.(type) { case *StarlarkSchema: - return v.Schema.Fields, nil + return v.Schema.Schema, nil case starlark.String: return v.GoString(), nil diff --git a/schema/schema_test.go b/schema/schema_test.go index ce080ab7a9..ec3812fcda 100644 --- a/schema/schema_test.go +++ b/schema/schema_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/pkg/errors" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" "tidbyt.dev/pixlet/runtime" "tidbyt.dev/pixlet/schema" ) @@ -137,16 +137,16 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) jsonSchema := app.GetSchema() var s schema.Schema json.Unmarshal([]byte(jsonSchema), &s) - require.Equal(t, schema.Schema{ + assert.Equal(t, schema.Schema{ Version: "1", - Fields: []schema.SchemaField{ + Schema: []schema.SchemaField{ { Type: "location", ID: "locationid", @@ -301,17 +301,17 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) jsonSchema, err := app.CallSchemaHandler(context.Background(), "generatedid", "foobar") - require.NoError(t, err) + assert.NoError(t, err) var s schema.Schema json.Unmarshal([]byte(jsonSchema), &s) - require.Equal(t, schema.Schema{ + assert.Equal(t, schema.Schema{ Version: "1", - Fields: []schema.SchemaField{ + Schema: []schema.SchemaField{ { Type: "text", ID: "generatedid", @@ -354,10 +354,10 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) _, err = app.CallSchemaHandler(context.Background(), "generatedid", "foobar") - require.Error(t, err) + assert.Error(t, err) } // Verifies that appruntime.Schemas returned by a generated field's handler is @@ -383,7 +383,7 @@ def main(): ` _, err := loadApp(code) - require.Error(t, err) + assert.Error(t, err) } func TestSchemaWithGeneratedIconNotAllowed(t *testing.T) { @@ -416,7 +416,7 @@ def main(): ` _, err := loadApp(code) - require.Error(t, err) + assert.Error(t, err) } func TestSchemaWithLocationBasedHandlerSuccess(t *testing.T) { @@ -440,11 +440,11 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) stringValue, err := app.CallSchemaHandler(context.Background(), "locationbasedid", "fart") - require.NoError(t, err) - require.Equal(t, "[{\"text\":\"Your only option is\",\"value\":\"fart\"}]", stringValue) + assert.NoError(t, err) + assert.Equal(t, "[{\"text\":\"Your only option is\",\"value\":\"fart\"}]", stringValue) } func TestSchemaWithLocationBasedHandlerMalformed(t *testing.T) { @@ -468,10 +468,10 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) _, err = app.CallSchemaHandler(context.Background(), "locationbasedid", "fart") - require.Error(t, err) + assert.Error(t, err) } func TestSchemaWithTypeaheadHandlerSuccess(t *testing.T) { @@ -495,11 +495,11 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) stringValue, err := app.CallSchemaHandler(context.Background(), "typeaheadid", "farts") - require.NoError(t, err) - require.Equal(t, "[{\"text\":\"You searched for\",\"value\":\"farts\"}]", stringValue) + assert.NoError(t, err) + assert.Equal(t, "[{\"text\":\"You searched for\",\"value\":\"farts\"}]", stringValue) } func TestSchemaWithTypeaheadHandlerMalformed(t *testing.T) { @@ -523,10 +523,10 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) _, err = app.CallSchemaHandler(context.Background(), "typeaheadid", "fart") - require.Error(t, err) + assert.Error(t, err) } func TestSchemaWithOAuth2HandlerSuccess(t *testing.T) { @@ -554,11 +554,11 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) stringValue, err := app.CallSchemaHandler(context.Background(), "oauth2id", "farts") - require.NoError(t, err) - require.Equal(t, "a-refresh-token", stringValue) + assert.NoError(t, err) + assert.Equal(t, "a-refresh-token", stringValue) } func TestSchemaWithOAuth2HandlerMalformed(t *testing.T) { @@ -586,8 +586,8 @@ def main(): ` app, err := loadApp(code) - require.NoError(t, err) + assert.NoError(t, err) _, err = app.CallSchemaHandler(context.Background(), "oauth2id", "farts") - require.Error(t, err) + assert.Error(t, err) } diff --git a/schema/toggle_test.go b/schema/toggle_test.go index 932a77da30..0f0db8e8b8 100644 --- a/schema/toggle_test.go +++ b/schema/toggle_test.go @@ -19,14 +19,14 @@ t = schema.Toggle( name = "Display Weather", desc = "A toggle to determine if the weather should be displayed.", icon = "cloud", - default = True + default = True, ) assert(t.id == "display_weather") assert(t.name == "Display Weather") assert(t.desc == "A toggle to determine if the weather should be displayed.") assert(t.icon == "cloud") -assert(t.default) +assert(t.default == True) def main(): return []